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.
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 — 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 target | npm equivalent | What it is |
|---|---|---|
FundamentalCore | @fundamental-engine/core | The pure physics — particles, bodies, forces, the integrator, formations, reactions. Zero platform imports. |
FundamentalPlatform | @fundamental-engine/dom | The six-phase frame scheduler (discover → read → compute → state → write → render) and the six registries. |
FundamentalVanilla | @fundamental-engine/vanilla | The imperative API — FieldField, mountField. One import; the host (UIKit / AppKit / RealityKit) is selected at compile time. |
FundamentalSwiftUI | @fundamental-engine/react | The 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.
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.
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.
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.