Getting started
Add the JoyDom Swift package to an app and render your first Joy DOM document in SwiftUI.
This guide walks through rendering a Joy DOM document in a SwiftUI app, from an empty project to a live view that reacts to events.
Requirements
- macOS with Xcode 15+ (Swift 5.9 toolchain).
- A deployment target of iOS 16 / macOS 13 or newer — the platforms the binary ships for. The alpha XCFrameworks are iOS + macOS only; the source package also builds for tvOS and watchOS.
- No source checkout — JoyDom is distributed as a precompiled Swift package you add via SPM.
Alpha
JoyDom ships as precompiled XCFrameworks (source not included) from
j0yhq/joydom-swift. Use the latest
release — the API may still change during alpha,
so pin the exact version you pick.
Creating your project
Set a product name, choose SwiftUI for the interface and Swift for the language, then Next and create.
Already have an app? Skip ahead to Adding JoyDom to your project.
Adding JoyDom to your project
JoyDom is distributed over Swift Package Manager from
j0yhq/joydom-swift as precompiled XCFrameworks.
Paste the package URL into the search field:
https://github.com/j0yhq/joydom-swiftJoyDOM library product to your app target.The JoyDOM product bundles the flexbox engine that powers JoyDom's layout (how it works), so there's nothing else to add.
Rendering a document
Add a document to your project. Drop a Joy DOM JSON file — say card.json — into your app
target so it's bundled as a resource.
{
"version": 1,
"style": {
".card": { "display": "flex", "padding": { "value": 16, "unit": "px" } },
"p": { "display": "flex" }
},
"breakpoints": [],
"layout": {
"type": "div",
"props": { "className": ["card"] },
"children": [{ "type": "p", "children": ["Hello Joy DOM"] }]
}
}Download card.json
Import the package.
import SwiftUI
import JoyDOMRender it. Seed a ComponentRegistry with the built-in primitives —
ComponentRegistry.shared is empty by design, so without withDefaultPrimitives()
every built-in node renders as a placeholder. (Decoding the bundled JSON into a Spec
is covered in Loading documents.)
struct CardScreen: View {
let spec: Spec
private let registry = ComponentRegistry().withDefaultPrimitives()
var body: some View {
JoyDom(spec: spec, components: registry)
}
}Build and run. JoyDom resolves the style cascade and lays the tree out through
FlexLayout — that's everything required to render. To resolve @media breakpoints, observe
diagnostics, or override a node inline, see Extras.
Where next
- Events — the binding/
emit/onEventcontract in depth. - Custom components — render the document's kebab-case node types with your own views.
- How it works — the decode → cascade → flexbox → SwiftUI pipeline.