Guides

The core engine

Skip every wrapper and drive the engine on a canvas you own. The core is zero-dependency TypeScript. For a managed canvas and an ergonomic class, reach for the TypeScript wrapper instead.

Install

npm i field-ui the engine itself — when you own the canvas

createField — your own canvas

When you want to place and size the canvas yourself, hand it to createField. You get the FieldHandle. This is the lowest-level entry point; the web component, the React adapter, and @field-ui/vanilla all wrap it.

TypeScript
import { createField } from 'field-ui';

const canvas = document.querySelector('canvas');
const field = createField(canvas, {
  accent: '#4da3ff',
  density: 1,
  attention: false,
  causality: false,
});

// the field reads every [data-body] element on the page.
// after you add or remove bodies, rescan:
field.scan();
The canvas is decorative. Position it fixed behind your content (position: fixed; inset: 0; z-index: 0; pointer-events: none) and mark it aria-hidden. Reduced motion is honoured automatically, and the loop pauses when the tab is backgrounded.
Want a managed canvas? @field-ui/vanilla creates and tears down the canvas for you — as a FieldField class or the mountField() function. See the TypeScript guide.

The force contract

A force is one small object — a token and an apply(body, particle, env) that nudges a particle's velocity. Every one of the 33 built-ins implements this exact contract, and the engine never special-cases any of them, which is why they compose. The shape:

TypeScript
import type { Force } from 'field-ui';

// Every force is one object: a token + an apply(body, particle, env).
// This is the exact contract all 33 built-ins implement.
const lift: Force = {
  token: 'lift',
  label: 'Lift',
  apply(b, p, env) {
    if (env.dist >= b.range) return;          // out of reach -> skip
    const f = (1 - env.dist / b.range) * b.strength * 0.5;
    p.vy -= f;                                // nudge the particle upward
  },
};
Registering your own. The built-in catalog is registered for you, and the registry that holds it lives inside createField — so authoring a brand-new force today means building against the Force contract at the engine level rather than passing it in as an option. The documented catalog covers most needs; compose forces with presets for bigger effects.