Joy DOM

Quickstart

Render your first Joy DOM document in five minutes.

This page gets you from zero to a rendered Joy DOM document in a React app in about five minutes. For a deeper walk through the model, follow the Tutorial after.

Prerequisites

A React 18+ app you can edit. A new Vite or Next.js project works fine.

Install

Install the React renderer and the spec package:

bun add @joy-dom/react @joy-dom/spec

@joy-dom/react exports the <JoyDom> component that turns a spec into rendered output. @joy-dom/spec exports the TypeScript types and the JSON Schema so your tooling can validate documents.

Write a document

Joy DOM documents are JSON. Save this as hello.json in your project:

{
  "version": 1,
  "style": {
    ".stack": {
      "display": "flex",
      "flexDirection": "column",
      "gap": {
        "value": 12,
        "unit": "px"
      },
      "padding": {
        "value": 24,
        "unit": "px"
      }
    },
    "h1": {
      "display": "flex",
      "fontSize": {
        "value": 32,
        "unit": "px"
      }
    },
    "p": {
      "display": "flex",
      "fontSize": {
        "value": 16,
        "unit": "px"
      },
      "color": "#475569"
    }
  },
  "breakpoints": [],
  "layout": {
    "type": "div",
    "props": {
      "className": ["stack"]
    },
    "children": [
      {
        "type": "h1",
        "children": ["Hello Joy DOM"]
      },
      {
        "type": "p",
        "children": ["Rendered natively from JSON."]
      }
    ]
  }
}

Why does every node have `display: "flex"`?

Joy DOM requires display to be set explicitly on every node. See §4.4 Special rules in the specification.

Render it

Import the JSON and pass it to <JoyDom>:

import {  } from "@joy-dom/react";
import type { Spec } from "@joy-dom/spec";
import  from "./hello.json";

export function () {
  return < ={ as Spec} />;
}

That's it. Boot your dev server - you should see the heading and paragraph styled per the JSON.

What just happened

  • version: 1 declares the spec revision (see §2.1).
  • style defines shared rules keyed by selector (see §4 Styles).
  • breakpoints is empty - responsive overrides arrive in tutorial chapter 3.
  • layout is the root node tree (see §3 Nodes).

Where next

Tutorial - walk through the document model, styling, breakpoints, custom components, and publishing as one connected story.

Specification - the numbered, deep-linkable contract for every supported node, property, and breakpoint condition.

Use cases - copy-paste documents for invoices, reports, forms, and resumes.

On this page