Sign in

Reference

Motion format 0.3

spec.md

Status: Draft · Version: motion/0.3 · what each version added: §10

What a motion is on disk: the files, their fields and the rules any tool can rely on. This document only grows: a later version adds to it and never changes the meaning of what is here.

1. What a motion is

A motion is a reusable look for narrated and explanatory video: how a film looks (ground, colour, type) and how it moves (how things arrive, change and leave). It is written so that a person or an agent can make a new film in it with any engine.

A motion holds no film. It has no story, script, scene list, timings or end card. A sample made in it is one example among many.

2. Files

A motion is a directory named after its slug. A copy taken into a project may sit in a directory of another name (motion/); its slug still names it:

<slug>/
  motion.json      identity, authorship and licence          required
  MOTION.md        how it looks and moves, for agents        required
  tokens.json      colours and faces, in the DTCG format     required
  poster.jpg       one representative frame                  required
  CREDITS.md       fonts, assets and sources                 required
  MOTION.<lang>.md a translation of MOTION.md                optional
  <tool>/          files one tool needs (§7)                  optional

No other file may sit at the top of a motion. Names are exact and case-sensitive.

Where many motions are kept together, a scoped motion's directory sits in a directory named after its scope with an @ before it: @ana/ledger-pencil/ (§3, Identity).

3. motion.json

A JSON object with these members and no others, except extension members (§7).

Member Required Value
spec yes "motion/0.3"; or "motion/0.2" for a motion without basedOn, or "motion/0.1" for one without scope and basedOn
scope no The GitHub username, in lowercase, of the person or organization that publishes the motion (since 0.2)
slug yes 3 to 40 characters of a-z, 0-9 and single hyphens, starting and ending with a letter or digit; the name of the directory it is published in (§2)
version yes A Semantic Versioning 2.0 version of this motion, for example "1.0.0"
name yes A localized string (§8) of at most 60 characters per language
line yes A localized string (§8) of at most 160 characters per language: one sentence saying what it looks like and what it is for
authors yes A non-empty array of { "name": string, "github": string }; github is a GitHub username
license yes { "text": SPDX, "code": SPDX }: text covers the documents, tokens and pictures; code covers any code under a tool directory and is required when there is any
lang no The BCP 47 tag of the language MOTION.md is written in; "en" when absent
tags no Up to 10 keywords, each of a-z, 0-9 and single hyphens, in English
basedOn no The motions this one builds on: an array of 1 to 10 { "id": string, "version": string }, each a motion's id (Identity) and, optionally, the version built on; no id twice, and never the motion's own (since 0.3)

Identity

A motion's id is @<scope>/<slug> when it has a scope, and <slug> when it does not: @ana/ledger-pencil, red-pencil. Two motions under different scopes may have the same slug. Only the owner of a GitHub account publishes under its scope; what an unscoped id means is for the collection that holds it to say (motionhub accepts none: every motion there has a scope). Tools name, fetch and credit a motion by its id.

Building on another motion

A motion made from another names it in basedOn, by its id and the version it started from: "basedOn": [{ "id": "red-pencil", "version": "1.0.2" }]. This is the credit tools show and follow; CREDITS.md still says what was taken and what changed, as its licence asks. A tool does not require a motion named in basedOn to be at hand.

An SPDX value is an SPDX license expression, for example "CC-BY-4.0" or "MIT".

{
  "spec": "motion/0.3",
  "scope": "ana",
  "slug": "lab-notebook",
  "version": "1.0.0",
  "name": { "en": "Lab Notebook", "zh-CN": "实验手记" },
  "line": { "en": "A squared notebook page where the diagram is drawn stroke by stroke as it is explained." },
  "authors": [{ "name": "Ana", "github": "ana" }],
  "license": { "text": "CC-BY-4.0", "code": "MIT" },
  "tags": ["hand-drawn", "line-art", "light"]
}

4. tokens.json

The motion's values in the Design Tokens Format Module of the W3C Design Tokens Community Group (DTCG), version 2025.10. Any tool that reads DTCG reads it.

  • It has a color group and a font group, each with at least one token.
  • color tokens are of type color; font tokens are of type fontFamily. A group may set $type once for its members.
  • A token name contains no $, {, } or ., and is written in English (it is an identifier).
  • Every colour and face the motion relies on is a token. A token's $description says what it is for, in any language.
  • Other groups are allowed and are read as plain DTCG. For timing, use duration tokens and cubicBezier tokens; seconds, not frames.
  • Values are literal or DTCG aliases ("{color.ink}"). No value refers to a file or a URL.
{
  "color": {
    "$type": "color",
    "ground": { "$value": { "colorSpace": "srgb", "components": [0.98, 0.98, 0.96], "hex": "#FBFAF5" }, "$description": "the page" },
    "ink": { "$value": { "colorSpace": "srgb", "components": [0.11, 0.16, 0.28], "hex": "#1B2A47" }, "$description": "every line and word" },
    "accent": { "$value": { "colorSpace": "srgb", "components": [0.81, 0.31, 0.2], "hex": "#CF4F33" }, "$description": "the one result, never decoration" }
  },
  "font": {
    "$type": "fontFamily",
    "display": { "$value": ["Shantell Sans", "LXGW WenKai", "cursive"] },
    "sans": { "$value": ["Atkinson Hyperlegible Next", "Noto Sans SC", "sans-serif"] }
  },
  "duration": { "$type": "duration", "enter": { "$value": { "value": 0.6, "unit": "s" } } },
  "easing": { "$type": "cubicBezier", "arrive": { "$value": [0.22, 1, 0.36, 1] } }
}

5. MOTION.md

Markdown, at most 16 KB, in the language lang names. It is what an agent follows to make a film in this motion, so it describes the look and the motion, never a particular film.

It has a level-two heading for each of these five topics. The heading starts with the English word, which tools match without regard to case; any words may follow it (## Motion 动法).

Heading Says
Essence The few traits that make a frame read as this motion at a glance, and what it is easily confused with
Colour (or Color) What each colour token is for, and what is never coloured
Type The faces and their roles, sizes, and how words sit in the frame
Motion How things arrive, change and leave; the easing; how motion relates to narration or music; what never moves
Avoid The mistakes this look invites, and what to do instead

Any other sections may follow, in any order. A number in the text says where it comes from when that matters: measured, from a source, or chosen.

MOTION.<lang>.md is a translation of MOTION.md into the language <lang> (a BCP 47 tag). It follows the same rules and says nothing MOTION.md does not.

6. poster.jpg and CREDITS.md

  • poster.jpg is a JPEG frame of a film made in the motion: between 960 and 3840 pixels wide, at most 500 KB. It shows the look, not a title card.
  • CREDITS.md names every font, image, sound, model or other asset the motion's files use or require, with its licence and where it comes from, and any work the motion learned from. A motion that uses none says so.

7. Extensions

Everything that belongs to one tool lives in that tool's space, and every other tool ignores it.

  • Directories. A tool keeps its files in a directory named after it (react/, remotion/): 2 to 40 characters of a-z, 0-9 and single hyphens.
  • Members. A tool keeps its own motion.json members under one member named x-<tool>, for example "x-remotion": { "fps": 30 }.
  • Rule. A tool reading a motion ignores directories and x- members it does not know, and does not report them. It never writes into another tool's space.

What several tools come to share moves into a later version of this format.

8. Languages

Part Language
File and directory names, member names, scope, slug, spec, version, license, tags, token names, the start of the five MOTION.md headings English (identifiers)
name, line A localized string: an object whose keys are BCP 47 tags and whose values are text in that language. en is required; other languages are optional
The body of MOTION.md, translations, $description, authors[].name, CREDITS.md, words drawn in a film Any language

9. Versions

A motion's version changes whenever any of its files change. A published version is never changed: a fix is a new version. A film that uses a motion keeps the copy it took.

spec names the version of this format. A tool that meets a spec it does not know does not guess its meaning. A tool that reads a version reads every version before it: a motion/0.1 motion is a motion/0.2 motion without a scope, and a motion/0.2 motion is a motion/0.3 motion without basedOn.

10. Versions of this format

Version Adds
motion/0.1 The format: five files, motion.json, tokens.json, MOTION.md, extensions, languages
motion/0.2 scope, and a motion's id @<scope>/<slug> (§3, Identity)
motion/0.3 basedOn: the motions a motion builds on (§3, Building on another motion)

This page is SPEC.md in the repository, rendered. Suggest a change