Guides

The Swift port

The same reciprocal field, native on Apple platforms — iOS 17+, macOS 14+, and visionOS 1+. It is a port of the JS engine, not a reinterpretation: the package layout, the API surface, and the physics mirror the npm packages one-to-one. Where they diverge, it is a bug or a documented platform difference.

Status: 44/44. The Swift port is conformance-checked against the JS engine (a 36-force golden test asserts the two planes agree) and ships all 44 FieldHandle methods as of #822. See Implementations for the full surface-by-surface status, and Parity below for platform-specific notes.

Install

There is no published SwiftPM registry release yet — consume it from source. The package lives in the repo's swift/ directory; its SwiftPM package name is Fundamental.

Package.swift
// Package.swift — depend on the package from source.
// Preview: there is no published SwiftPM registry release yet, so point at
// a local checkout of the repo's swift/ directory (a .package(url:) door comes later).
dependencies: [
  .package(path: "../Fundamental/swift"),
],
targets: [
  .target(name: "App", dependencies: [
    .product(name: "FundamentalSwiftUI", package: "Fundamental"),
  ]),
]

To see it run before wiring it into your own app, build the bundled Field Lab demo: swift run FieldLab from swift/ (a packaging script, swift/Scripts/release-fieldlab.sh, produces an app bundle).

Packages — one-to-one with npm

Four libraries, each the mirror of an npm package. FundamentalCore imports zero platform code, exactly as @fundamental-engine/core imports zero DOM.

Swift targetnpm equivalentWhat it is
FundamentalCore@fundamental-engine/coreThe pure physics — particles, bodies, forces, the integrator, formations, reactions. Zero platform imports.
FundamentalPlatform@fundamental-engine/domThe six-phase frame scheduler (discover → read → compute → state → write → render) and the six registries.
FundamentalVanilla@fundamental-engine/vanillaThe imperative API — FieldField, mountField. One import; the host (UIKit / AppKit / RealityKit) is selected at compile time.
FundamentalSwiftUI@fundamental-engine/reactThe declarative adapter — FieldView, .fieldBody(), .fieldBurst(), the fieldHandle environment value.

SwiftUI — FieldView + .fieldBody()

The declarative door. FieldView mounts the field surface; any view inside becomes a body with the .fieldBody(...) modifier — the Swift analogue of the data-body attribute. It accepts the same token vocabulary and tuning as the web.

SwiftUI
import FundamentalSwiftUI

struct ContentView: View {
  var body: some View {
    ZStack {
      // the field surface — accepts every FieldOptions value
      FieldView(options: .init(accent: "#4da3ff", render: .dots))

      // any view becomes a body — the Swift analogue of [data-body]
      Text("pull me")
        .fieldBody(tokens: ["attract"], strength: 1.2, range: 150)
    }
  }
}

Vanilla — the imperative API

For UIKit/AppKit or any non-SwiftUI host, FieldField mirrors new FieldField() / mountField() from the vanilla JS API.

Swift
import FundamentalVanilla

// managed mount — mirrors new FieldField() / mountField()
let field = FieldField(in: myView)            // myView: UIView or NSView
field.scan()                                  // discover bodies in the view tree
field.setFormation("wells")
field.burst(at: tap.location(in: myView))     // a CGPoint from a gesture
// …
field.destroy()

visionOS — volumetric, 3D-native

The Swift engine is 3D-native: every position, velocity, and force is a SIMD3<Float>. The JS engine is 2D only because the DOM and Canvas are — that constraint doesn't exist here, so on visionOS depth is a real axis, not a projection trick. Any RealityKit entity hierarchy can host the field.

visionOS
import FundamentalVanilla

// any RealityKit Entity hierarchy can host the field; the simulation runs in
// native 3D — depth is a real axis, not a projection trick.
let host = RealityFieldHost(root: rootEntity, width: 1.0, height: 0.6, depth: 0.4)
let field = FieldField(host: host)

Parity

The Swift port ships 44/44 FieldHandle methods — full parity with the JS engine as of #822. The core force set, the scheduler and registries, formations, the interactive scenes, and all six advanced methods (addAgent, sample, on, readParticleIds, readParticleChannels, registerOverlay) are implemented and pass the cross-plane conformance gate.

The full method-by-method breakdown is on the parity matrix page. Some methods behave differently by platform design — setRender and setOverlay are host-owned in the native render loop; scrollV reads from UIScrollView velocity; scan is called by the SwiftUI integration layer rather than manually. These are documented in the parity matrix notes column.

The deeper architectural story — why the same engine can run on the web, in WebGL, headless, and natively on Apple platforms behind one host seam — is in One Engine, Four Runtimes. The seam itself is the platform layer; the runtime handle is the FieldHandle.