Fundamental · a physics engine for interfaces

Elements have mass.

Elements attract, repel and settle like real matter, so a layout shows its relationships instead of listing them. Nothing on this page is animated — every motion you can see is the field resolving. You add a data-body attribute; the runtime measures and hands back live --field-* variables you style with.

You can label everything urgent. You cannot make everything heavy. Priority becomes a force, not a flag — emphasize one thing, and the rest yield.

Category  add a data-* attribute, get --field-* back For  design engineers · AI-product builders · component-library authors Parity  js · swift · kotlin — six forces, identical output, checked in CI Maturity  0.x preview — shipping in production apps, no third-party adopters yet
density · bodies · particles · query readable projection css · json policy limited
A real interface

A real interface you’d actually build.

An inbox of real unanswered questions, ranked by urgency — recency, votes, and views become mass. But the page holds one fixed attention budget, so brightening one ask dims the rest. No particle swarm; the measurement comes back as type and ink.

Open this example →
Try it

Change a data-* and watch the field answer.

Every control rewrites one attribute on the real element to the right — the same data-* you'd author. The engine re-reads it and the field responds. That's the whole surface: attributes in, motion out. Move your cursor through it, too.

data-body="attract"
The wedge

Make model output you can read at a glance.

A model hands you answers; it rarely shows how sure it is. Make each claim a body in the field, and confidence becomes weight, agreement becomes proximity, and contradictions pull apart — so a shaky answer looks shaky and its sources are one hop away, before anyone acts on it. The interface projects that state as type and layout; an agent reads the same field as JSON through field.query(). The same deterministic math drives the Evidence and Search studies.

How it works

Declare, influence, read, reveal, govern.

Five verbs are the whole loop. You declare host objects into the field; forces influence them through declared channels; you read the state back; projections reveal it; policy governs what may run and what an agent may read.

  1. DeclareHost objects become bodies — a data-body attribute, addBody(), or a declared edge.
  2. InfluenceForces act through declared channels, accumulated centrally — deterministic and replayable.
  3. Readquery() and snapshot() expose the field as plain, serializable state.
  4. RevealProjections express that state through CSS variables, DOM attributes, JSON, native views, or overlays.
  5. GovernPolicies, budgets, redactions, lane lints, and reduced-motion rules constrain what runs and what an agent reads.

Want the exact API? Read the docs. Want the live engine? Open the manual. Want the substrate proof? One field, two readings →

Why it’s different

Most interfaces store meaning, then fake its effects.

You can’t style everything as urgent — the attention budget is conserved. Express “these are related,” “the user has dwelled here,” or “this is unstable” as first-class runtime state, instead of hand-rolling badges, spinners, and bespoke animation for each. See conserved attention →

data-*you author measureruntime --field-*runtime writes back you styleCSS
You author meaning; the field returns measurement.

Stop building the systems that exist because the DOM is blind.

The DOM can’t see what matters, what’s related, or what’s gone stale — so teams build that sight by hand, again and again. Fundamental gives the DOM a continuous answer, and a whole category of code stops being yours to write and maintain.

  • Priority you don’t store or sort. Importance is a live field reading (--d, with --field-density as the field-namespaced alias), not state you keep in a store and re-sort on every change. See it work →
  • “Everything is P1,” solved by a law. Attention is one conserved budget — emphasize one thing and the rest necessarily yield. The normalization pass teams enforce with scoring schemes and meetings becomes something the runtime cannot violate. See it work →
  • Relationships you can read. Declared associations become field-visible structure — a Field Pattern decides when association becomes coupling, not adjacency lists and graph traversal you maintain by hand. See it work →
  • Staleness without timers. Recency and decay are a force in the runtime, continuous, not a cron job or a computed column you babysit. See it work →
  • One model, always current. The field re-resolves every frame, so a priority shift doesn’t fire a sort-and-re-render pass — the readout is simply already current. See it work →

Fundamental doesn’t hand you a better abstraction over these jobs. It makes the question each one answered — what matters, what’s related, what’s stale — answerable by the field, so the job itself goes away.

Install

Add it to the stack you already have.

One package per framework — pick the one for your stack and you’re done. Each bundles the engine (core + the DOM binding) for you; there’s nothing to wire together.

Start here npm i @fundamental-engine/vanilla Plain TS / JS, no framework — the typed FieldField class; one call mounts a field. This card is itself a live field body: it accretes the swarm and fills as it gathers. Guide →
npm i @fundamental-engine/react React — the <FieldField> component + useFieldField hook. Guide →
npm i @fundamental-engine/elements Any framework or plain HTML — the <field-root> web component. Guide →
npm i @fundamental-engine/three Three.js / WebGL — the swarm as a THREE.Points layer. Guide →

Own the canvas / building your own renderer? @fundamental-engine/core is the renderer-agnostic engine — you supply a host (Core guide). You don’t install @fundamental-engine/dom directly — the packages above already bundle it for you.

No build step? Import from a CDN (playground / prototyping only): import { createField } from 'https://esm.sh/@fundamental-engine/vanilla'

The full package map and an install-to-reacting-headline walkthrough live in the docs.

Hosts

One engine, many hosts.

The core computes the field against plain data and imports zero DOM. A thin host binds it to a host — so the same physics runs on the web, natively, in your renderer, or headless:

  • Web@fundamental-engine/dom binds the engine to the page: every [data-body] element a body, feedback returned as --field-* variables. The primary surface — and what this page runs on.
  • Native — a Swift port runs the same field on Apple platforms (Metal / SwiftUI), and a Kotlin port runs it on Android (Jetpack Compose, plus a non-Compose View/Canvas host) — both free of the browser’s compositing ceiling. The Field Lab is the showcase: a native app to explore every force live.
  • Your renderer@fundamental-engine/three drives a THREE.Points swarm in your own WebGL scene; the read primitives (sample, readParticles, addField) bind the engine to anything that draws.
  • Headless — no DOM, no canvas: records become bodies and relationships become edges, and a tool reads the field through query() and snapshot(). The smallest conformant host — for servers, tests, and agents.

How the hosts relate — and what’s at parity across them — in Implementations.

Trust

Built to be inspected.

  • Zero runtime dependencies. The core engine ships with none.
  • Signals-first by default. A field renders nothing unless you ask for it — the invisible field is the baseline.
  • Accessible by construction. Semantic HTML stays the source of meaning; reduced motion removes motion, not meaning — enforced and linted.
  • Measured, not guessed. Sub-millisecond compute per frame at real-page scale; fill-rate is the real budget and is measured on real hardware.
  • Stable 0.x surface, cross-plane conformance. Code-verified docs, a frozen public API, and shared-physics conformance across web, Apple, and Android.
The full engine, live

36 forces. 64 patterns. 8 presets. One 0.x API.

Everything above is built from one contract: data-* in, --field-* out. The complete force-by-force manual — every force, preset, and system behaviour, each demo running live on the real engine — now has its own page, so the homepage can stay about the substrate.

Or jump straight to a surface: the API · patterns · the force catalog.