The CLI — headless renders
Render a .motion project to a file without opening the editor. The app
executable is the command line:
Premation render Promo.motion --comp Main --out promo.mp4It drives the same engine — premation-engine, the native process that draws
the viewport — with the same deterministic frame loop and the same ffmpeg encode
the Export dialog and the Render Queue use. There is no second renderer that can
drift out of step, and no window is opened: the file the CLI writes is the file
the editor would have written.
It runs on your own machine: no server, no account.
For the video formats it uses $FFMPEG_PATH if set, otherwise the ffmpeg that
ships with the app, otherwise ffmpeg on your PATH. It does not use a copy
repaired or chosen inside the app — see ffmpeg & codecs.
The four commands
| Command | What it does |
|---|---|
render <project> | Renders one composition to one file. With no --out, writes beside the project (Promo.motion → Promo.mp4). |
reframe <project> --aspect 9:16 | Auto-reframes the composition to another shape, then renders it. Aspects: 9:16, 1:1, 4:5, 16:9, 4:3. |
captions <project> --out subs.srt | Transcribes the composition’s audio to .srt or .vtt. Needs an OpenAI key in the desktop keystore. |
comps <project> | Lists the compositions — name, size, fps, duration, id — so a script can discover what to render. |
To burn subtitles into a render, pass --captions subs.srt to render. That
replaces any captions already in the composition, so re-running a pipeline does
not stack a second set of caption layers over the first.
The edits a render asks for run in a fixed order, on a saved copy of the project
that is then rendered: --commands, then a --data row, then --captions, then
--aspect. Your project file is never changed.
The options you will actually use
premation render Promo.motion \
--comp Main --range 0-119 --scale 0.5 --format webm --transparent \
--out preview.webm| Option | Meaning |
|---|---|
--comp <name|id> | Which composition. Matched by id, then exact name, then case-insensitively. |
--format | mp4, mov, webm, gif, hdr10, hlg, png-sequence, jpg-sequence, exr-sequence, png. Usually inferred from --out. |
--range 0-119 | Inclusive frame range. --start and --end (inclusive) give the same range separately. |
--fps <n> | Override the composition’s frame rate. |
--scale / --width / --height | Output size. One dimension keeps the aspect. |
--quality | high (default), medium, draft. |
--prores | mov only: proxy, lt, 422, hq, 4444 (default). Refused on other formats rather than silently ignored. |
--transparent | Force an alpha channel on. |
--captions <file> | Import an .srt or .vtt and burn it in before rendering. |
--commands <file> | Apply a recorded command log to the project before rendering. |
--data <file> | A CSV or JSON table — one render per row. See below. |
--json | One JSON object per line, for scripts. |
--quiet / --log <file> | Silence progress / mirror output to a file. |
--format hdr10 (PQ) and --format hlg write a 10-bit HEVC MP4 in BT.2020,
encoded by the engine. An ffmpeg without libx265 writes H.264 High 10 instead
and says so. See HDR10 and HLG.
--out overwrites. The in-app Render Queue never does — it suffixes
(2) to protect files — but a pipeline needs its artifact at a known path,
so the CLI takes the opposite side of that trade.
Batch renders from a spreadsheet
Author one composition, expose the layers you want driven as template fields, and render one file per row:
premation render LowerThird.motion --data people.csv --out "out/{index}-{name}.mp4"name,role
Ada Lovelace,Mathematician
Grace Hopper,Rear AdmiralColumns fill the template fields with the same id; extra columns are ignored;
missing columns keep the authored value. --from-row 40 resumes a crashed
batch without re-rendering the first 39. The --out pattern must contain a
{token} so rows cannot overwrite each other — the CLI refuses to run
otherwise.
Good to know
-
Nothing but the engine boots. The headless process opens no window and starts no application menu, auto-updater, managed backend, account session or AI provider channel. The engine renders, the same job the Export dialog runs.
-
Exit codes are honest.
Code Meaning 0The file was written 1The render failed. The reason is the last line printed 2The command line was wrong. Nothing was rendered A bad command line exits
2immediately — a typo does not cost a GPU boot to discover. A silent composition passed tocaptionsis reported, not written out as an empty file. -
A batch that fails on one row keeps going. The failed row is recorded, the rest render, and the run exits
1with every failure named — so a pipeline never reads “39 of 40” as green. -
A stalled render is stopped. A render that makes no progress for 15 minutes is stopped and reported. The clock resets on every frame, so it bounds the gap between frames, never the length of the render.
-
It runs while the editor is open. Each render is its own process.
-
On Windows, use
--logto see output. A packaged Windows app has no console attached, so a run fromcmdor PowerShell gets the exit code and nothing else.--log render.logmirrors every line to a file. The exit code is reliable either way.
JSON output
--json prints one object per line:
{"event":"progress","fraction":0.5,"percent":50}
{"event":"warning","message":"warning: Layer \"Clip\" points at media this machine cannot resolve (local-path): C:\footage\a.mp4"}
{"event":"done","message":"Wrote …","outPath":"…","frames":120,"width":1920,"height":1080,"fps":30,"elapsedMs":48210,"warnings":[]}A failure prints {"event":"error","message":"…"} and exits 1.
Footage in a project
A saved .motion bundle carries its own footage, so a project moved to another
machine renders what it was authored with. Two things still travel badly, and the
CLI names both rather than hiding them: media referenced by an absolute path
(printed as a warning naming the layer and the path), and footage imported into a
project that was never saved as a bundle (warned, and the render refuses
outright if the frame would be visibly wrong rather than shipping a hole).
What it does not do
- No parallelism. One render at a time, one row at a time. Run several processes if your machine has the GPU headroom.
- No audio-only or interchange formats. WAV, Lottie, project JSON, EDL, OTIO, FCPXML, ALE and MOGRT remain editor features.
- No queue. Pausing, resuming and reordering belong to the Render Queue panel.