Format overview
A .jdf file is a single JSON document with six top-level fields. The full JSON Schema is at spec/jdf-schema.json ↗.
Top-level shape
| Field | Required | What it does |
|---|---|---|
$jdf | yes | Format version (semver, e.g. "1.0.0") |
meta | yes | Title, author, page size, margins, language, keywords |
styles | no | Reusable named style definitions (referenced by name from elements) |
resources | no | Embedded fonts and base64 images |
header | no | Repeating header (template string with vars or full element tree) |
footer | no | Repeating footer (same shape) |
pages | yes | Array of pages, each with its own elements[] |
Minimal valid document
{
"$jdf": "1.0.0",
"meta": { "title": "Hello" },
"pages": [{
"elements": [
{ "type": "text", "content": "Hi there" }
]
}]
}
Page layout
Page sizes
Named (A4, A3, A5, Letter, Legal, Tabloid) or custom {width, height} in millimeters:
"meta": { "pageSize": "A4" }
"meta": { "pageSize": { "width": 250, "height": 200 } }
Orientation
"portrait" (default) or "landscape". Doc-level (meta.pageOrientation) sets the default; per-page (page.pageOrientation) overrides.
Margins
Object with top, right, bottom, left in millimeters (any unit if you've set meta.unit). A4 default: {top: 25, right: 22, bottom: 25, left: 22}. The content area for default A4 is therefore 166 × 247 mm.
Positioning units
Positions and dimensions are millimeters by default. Font sizes are points. Override with meta.unit: "mm" | "in" | "pt" | "px".
Element types
Every page has an elements[] array. Each element has a type discriminator:
| Type | Use for |
|---|---|
text | Paragraphs, headings (with heading: 1-6), labels |
richtext | Inline-formatted text — bold, italic, links, color spans |
image | Embedded base64 images (via resources) or referenced URLs |
table | Headers, rows, alternating colors, configurable borders |
list | Ordered, unordered, nested with per-item type override |
shape | rect, circle, ellipse, line, SVG path |
collapsible | Expandable section with nested elements (interactive) |
toc | Auto-generated table of contents from headings |
See the element reference for every property of every type.
Styles
Define reusable styles in styles and reference them by name from any element:
{
"styles": {
"h1": { "fontSize": 22, "fontWeight": "bold", "color": "#0f172a" },
"body": { "fontSize": 11, "lineHeight": 1.6 }
},
"pages": [{
"elements": [
{ "type": "text", "content": "Title", "style": "h1" },
{ "type": "text", "content": "Body text", "style": "body" }
]
}]
}
A style reference accepts: a single name ("h1"), an array (["body", "highlighted"] — merged left-to-right), or an inline object.
Headers and footers
Template form (one-liner)
"footer": {
"content": "{{title}} — page {{pageNumber}} of {{totalPages}}",
"style": "muted"
}
Variables: {{pageNumber}}, {{totalPages}}, {{title}}, {{author}}.
Element-tree form (full layout)
"header": {
"height": 15,
"elements": [
{ "type": "image", "resource": "logo", "position": { "x": 0, "y": 0 }, "width": 30 },
{ "type": "text", "content": "Confidential", "position": { "x": 100, "y": 3 } }
]
}
Resources
Embed images as base64 once, reference them by key from any element:
{
"resources": {
"images": {
"logo": {
"src": "embedded",
"mimeType": "image/png",
"data": "iVBORw0KGgoAAA..."
}
}
},
"pages": [{
"elements": [
{ "type": "image", "resource": "logo", "width": 40 }
]
}]
}
Internal navigation
Link to another page with a #page-N hash:
{ "type": "text", "content": "See appendix",
"link": "#page-5" }
// or the explicit form
{ "type": "text", "content": "See appendix",
"link": { "type": "internal", "target": "#page-5" } }
External URLs: "link": "https://example.com".