The Koezu deck format
Version 3 · open specification · JSON Schema · published at koezu.com/format
A Koezu deck is a presentation as one JSON object. Koezu saves it inside a web page, so the file opens in Koezu and
in any browser. The same JSON can stand alone as a .json file. This document describes that object well enough that a
program or an AI agent can create, read and change decks without Koezu. Edits are safest through the
edit operations at the end, which Koezu's own AI uses.
Contents: Files · The deck · Slides · Objects · Text · Colours and fonts · Animations · Languages · Recording · What Koezu changes when it opens a deck · Edit operations · Tools
Files
| File | What it is |
|---|---|
.html |
The Koezu app page with the deck in it. The deck is the JSON inside
<script type="application/json" id="deck-data">…</script>, which comes
before the app's <script id="dk-script">. Every < in the JSON is
written <, so the block cannot end early. To change the deck, replace only that block's text; the rest of the
page is the app.
|
.json |
The deck object alone. Koezu opens it (File › Open). |
Slide show .html |
The same, with only the code that plays a deck (File › Save as slide show). The deck block is the same. |
A file saved by Koezu may also hold, in its page: <style id="dk-fonts"> (embedded fonts, only the
characters used) and <script type="text/plain" data-vendor="…"> blocks (libraries kept for
offline use). Neither is part of the deck.
The deck
{
"format": "deckit",
"version": 3,
"title": "Damped free vibration",
"size": { "w": 1920, "h": 1080 },
"theme": { "key": "paper", "colors": { "bg": "#ffffff", "surface": "#f2f4f8", "text": "#16202e", "muted": "#5b6678", "accent": "#2f5bea", "accent2": "#e0692f" }, "fonts": { "heading": "IBM Plex Serif", "body": "IBM Plex Sans" } },
"master": { "id": "master", "background": null, "hf": { "number": false, "footer": false, "date": false, "footerText": "", "dateText": "", "skipTitle": true }, "elements": [ … ] },
"layouts": [ { "key": "titleContent", "name": "Title and content", "background": null, "elements": [ … ] } ],
"slides": [ { "id": "s1", "layout": "titleContent", "elements": [ … ] } ]
}
| Field | Required | Meaning |
|---|---|---|
format |
yes | Always "deckit" (Koezu's earlier name; it stays for compatibility). |
version |
The format version, a whole number (3 now). Older decks are brought up to date when opened; a newer one opens as well as it can. | |
slides |
yes | At least one slide, in order. |
title |
The deck's name. | |
size |
The slide size in pixels, { w, h }. 1920 × 1080 (16:9) unless set; 1440 × 1080 is 4:3. All positions are in this
space.
|
|
theme |
colors (the six below) and fonts: heading, body, optional
headingWeight, ja (the Japanese font that goes with them) and math (stix2
or fira; TeX's own Latin Modern when missing). key names a built-in theme: lab, paper, lecture,
academic, accessible, kyoto, graphite, midnight.
|
|
master, layouts |
The slide master and its layouts, as in PowerPoint. Each has elements (objects drawn under every slide that uses
it; objects with a placeholder are only the template for new slides) and background. A layout has a
key that slides name. Without them, the default master and six layouts are used: title, titleContent, twoContent,
section, titleOnly, blank.
|
|
id |
The deck's own id (Koezu uses it for autosave). | |
embedFonts |
false to save without embedded fonts. |
|
pptxFonts |
true to put the deck's Koezu fonts inside exported PowerPoint files (off unless set). |
|
recording |
A recorded presentation (Recording). | |
mathCache |
Typeset equations, so they show without the math engine: keys are D|<latex> (display) or
I|<latex> (inline), prefixed stix2| or fira| for those math fonts; values are
<svg…>. Optional; rebuilt when missing.
|
|
lang, langBase, tr, trFrom |
Other languages (Languages). | |
share |
This copy's link to a shared deck (room and keys). Never copy it into another deck. |
Slides
| Field | Meaning |
|---|---|
id |
Unique among slides. |
layout |
A layout key. |
elements |
The objects, first drawn first (later ones are on top). |
background, bgGrad |
background: null (the layout's or the master's) or a colour. bgGrad: a gradient,
{ type, angle, stops: [{ pos, color }] }, which wins over the colour.
|
notes |
Speaker notes as plain text. notesHtml holds them formatted (Text); when both are present,
notesHtml wins and notes is its plain text.
|
hidden |
true to skip the slide in a slide show. |
transition, trDir, trDur, advance |
The transition into this slide (none, fade, push, wipe, split, reveal, cover, uncover, zoom, flip, circle), its direction, its length in seconds, and seconds before moving on by itself. |
noClick |
true: a click does not move to the next slide. |
anims |
Animations (below). |
hf |
Header and footer for this slide, as master.hf. |
comments |
[{ id, author, text, t (ms since 1970), x, y, replies: [{ id, author, text, t }], done }] |
Objects
Every object has:
| Field | Meaning |
|---|---|
id |
Unique in the whole deck (slides, master and layouts). Letters, digits, _ . : -. |
type |
shape (also text boxes), image, table, chart, math,
live, media. Other types are dropped.
|
x, y, w, h |
Position and size in slide pixels (top-left corner). |
rot |
Rotation in degrees, clockwise. |
opacity |
0 to 1. |
locked, name, alt, decorative |
Not movable; the name in the Selection pane; alt text for screen readers; true when it carries no meaning. |
link |
A web address (https:, mailto:, tel:) or another slide,
#slide-<number> (1-based).
|
grp |
Groups it belongs to, outermost first: ["g1", "g2"]. All members of a group are on the same
slide.
|
placeholder |
title, subtitle, body, body2, date, footer,
number: it takes its place and style from the layout.
|
shape
A preset shape with optional text. A text box is "shape": "none".
shape (PowerPoint preset names: rect, round, ellipse, triangle, diamond, hexagon, arrow, chevron, star, cloud,
flowChartProcess, wedgeRectCallout, line, arrowline … over 180), html (its text), fill,
stroke, strokeWidth, radius, dash, font,
fontSize (px), color, bold, italic, underline, strike,
align (left, center, right, justify), valign (top, middle, bottom), lineHeight,
pad, cols, colGap, autofit, flipH, flipV,
arrowStart, arrowEnd, adj (shape adjustments), gradient, shadow.
image
src (a data: URL: png, jpeg, gif, webp, bmp, svg, avif; or an https: address),
fit (cover, contain, fill), crop, radius, stroke, strokeWidth,
mask (a shape the picture is cut to), adj (brightness, contrast, blur …), recolor,
shadow.
table
cells: rows of cells, each cell rich text; every row has the same number of cells.
header, totalRow, banded, bandedCols, firstCol,
lastCol, font, fontSize, color, headerFill,
headerColor, bandFill, borderColor, borders (all, outside, inside, horiz, none),
borderW, cellPad (normal, narrow, wide, none), colW and rowH (widths and heights
as fractions of the table's), merges ([{ r, c, rs, cs }]: a block from its top-left cell),
cs (cs[r][c]: one cell's { fill, align, valign } or null).
chart
kind (column, bar, line, area, pie, doughnut, scatter),
data: { cats: [...], series: [{ name, values: [numbers] }] } (for scatter, cats are the x values),
title, legend (bottom, right, top, none), labels, grid, stacked,
style, axisX, axisY, font. Each series has as many values as there are
categories.
math
latex (LaTeX, without $), display (true: a display equation),
fontSize, color, align, eqNum (numbered equations). Inline math inside any text
is written $…$, display math $$…$$.
live
A live block: a small web page that runs on the slide, in a sandboxed frame with no network.
code (HTML with its own <style> and <script>), title,
params, exportShot (a picture used in exports), shotDelay. params is
{ name: { type, label, value, min, max, step, options } } with type one of number, bool, color, text,
longtext, select; the presenter changes them while presenting.
Inside the block: window.PARAMS (the parameters), window.THEME (the colours), and the CSS variables
--bg --fg --muted --acc --acc2 --surf --font-heading --font-body. Fonts come from the theme. Pictures must be
data: or blob:.
media
kind (video, audio, online), src (a data: URL, or a YouTube or Vimeo address for online),
name, autoplay, loop, muted, hideInShow, start,
end (seconds), poster, and the video edits (fadeIn, fadeOut,
volume, speed, vcrop).
Text
Rich text (an object's html, table cells, notesHtml) is a small set of HTML:
-
Tags:
b strong i em u s strike del ins br ul ol li div p span sub sup code font a blockquote small mark h1–h6 pre. -
Attributes:
stylewith color, background-color, font-weight, font-style, text-decoration, font-size, font-family, letter-spacing, text-transform, vertical-align, margin-left, padding-left, text-align, line-height, list-style-type, text-indent;hrefona(http, https, mailto, tel, or#slide-<number>). -
Everything else is removed: other tags lose their tag and keep their text;
script,style, frames, pictures and form controls are removed with their content; event handlers andjavascript:links are removed. - Fields:
{n}(slide number),{date},{footer}in footer placeholders. - Math:
$…$inline,$$…$$on its own line.
Colours and fonts
A colour is one of: a theme colour theme:bg, theme:surface, theme:text,
theme:muted, theme:accent, theme:accent2 (optionally lighter or darker:
theme:accent+40, theme:accent-25); #rgb, #rrggbb, #rrggbbaa;
rgb()/rgba()/hsl(); a CSS colour name; none. Use theme colours, so a deck
follows its theme.
A font is theme:heading, theme:body, or a family name (web fonts such as IBM Plex Sans, Inter, Noto Sans
JP; office fonts such as Calibri, Arial).
Animations and transitions
slide.anims is the order in which effects play:
{ "id": "a1", "el": "<object id>", "cls": "entr", "type": "fly", "dir": "left", "start": "click", "dur": 0.5, "delay": 0 }
cls: entr (entrance: appear, fade, fly, float, wipe, split, zoom, grow, bounce, wheel, shape),
emph (emphasis: pulse, spin, growShrink, teeter, flash, transp, wave), exit (disappear, fadeOut, flyOut,
floatOut, wipeOut, zoomOut, shrinkTurn), motion (a motion path; path in PowerPoint's path syntax).
start: click, with (the previous one), after (the previous one). Text can build one paragraph at a time (seq: "para").
Languages
A deck can hold itself in several languages. The language shown is in the fields above, and lang names it.
tr holds the others as { "<lang>": { "<unit>": "text" } }, where
a unit names one piece of text by where it is: e:<object>:html,
e:<object>:cell:<row>:<col>, e:<object>:title,
e:<object>:cat:<i>, e:<object>:series:<i>,
e:<object>:p:<param>, e:<object>:alt, s:<slide>:notes (rich text),
s:<slide>:hf:footerText, d:title. langBase is the original language;
trFrom keeps, per language and unit, a hash of the original text each translation was made from, so Koezu can tell
which translations are out of date. A program that edits the shown text should leave tr alone; Koezu marks the changed
translations for updating.
Recording
recording holds a recorded talk as a timeline, not pixels: segs (one per slide visit, each with
audio as a data: URL, optional camera, events (what happened when: steps, ink,
laser, live-block input), cuts (removed spans in ms), words), and camera,
captions ({ lang, show, burn, tracks: { <lang>: [{ seg, a, b, text }] } }), music,
mix, and dubs: a dubbed voice per language ({ <lang>: { provider, voice, voiceName, segs: { <seg id>: { audio, hash } }, approved: { by, at } | null, disclose,
use } }), spoken from that language's captions. A dub is used in an exported video only when it is approved and every recorded slide's dub
is up to date (hash). Koezu draws the video from the slides when it is exported, so the recording stays editable. A
program should keep recording as it is.
What Koezu changes when it opens a deck
Koezu checks every deck it opens, from a file, the clipboard, an AI answer or the server, and repairs what it can:
- Objects of an unknown type, tables whose rows differ in length and charts without
dataare dropped. - Missing ids are made; positions that are not numbers become 0 (sizes 100).
-
Text is cleaned as above; a colour that is not a colour becomes the default; addresses other than
data:,https:andblob:are removed. - A missing master or layouts get the defaults; a missing size is 1920 × 1080; a missing theme is Paper.
- Older versions are brought up to date (version 1 → 2: the slide master and layouts; 2 → 3: lines by their end points).
Koezu's validator reports these as errors (something is dropped, or the deck does not open) and warnings (something is changed).
Edit operations
Edit operations are the way to change a deck. Koezu's AI and its agent tools use them. Each is a JSON object with an
op; a list is applied in order, and the whole list is one undo step in Koezu. Operations that name something not in the
deck are skipped and counted. In short:
| op | Fields |
|---|---|
| addSlide |
layout, title, subtitle, bullets, bulletsRight, notes, after (slide id, current, end), ref (a name later ops use as
"@name")
|
| deleteSlide · moveSlide | slide · slide, to (1-based) |
| setTitle · setBullets · setText | slide, text · slide, bullets · el, html |
| addText · addShape · addLine | slide, html/shape/kind, x, y, w, h (or x1, y1, x2, y2), colours, fontSize … |
| addEquation · setEquation | slide, latex, x, y, fontSize, numbered · el, latex |
| addChart · addTable | slide, kind, title, cats, series · slide, rows |
| addLive · updateLive | slide, template (oscillator, chart, quiz, timer) or code, params · el, code, params, title |
| update · delete | el, props (x, y, w, h, rot, fontSize, color, fill, stroke, bold, align …) · el |
| setNotes · setBackground · setTheme · setDeckTitle | slide, text · slide, color · key · title |
| animate · setAlt · addPicture | el, effect, start · el, alt · slide, picture |
slide is a slide id, a 1-based number, current, or @ref. el is an object id.
Tools
A JSON Schema of the structure above, for editors, validators and other tools, is at koezu.com/schema/deck-3.json. Koezu's own command-line tool and MCP server for AI agents (create, outline, edit with pictures of the changed slides, render, validate, export) are not released publicly yet.