Skip to Content
Command lineThe CLI (local renders)

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.mp4

It 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

CommandWhat 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:16Auto-reframes the composition to another shape, then renders it. Aspects: 9:16, 1:1, 4:5, 16:9, 4:3.
captions <project> --out subs.srtTranscribes 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
OptionMeaning
--comp <name|id>Which composition. Matched by id, then exact name, then case-insensitively.
--formatmp4, mov, webm, gif, hdr10, hlg, png-sequence, jpg-sequence, exr-sequence, png. Usually inferred from --out.
--range 0-119Inclusive frame range. --start and --end (inclusive) give the same range separately.
--fps <n>Override the composition’s frame rate.
--scale / --width / --heightOutput size. One dimension keeps the aspect.
--qualityhigh (default), medium, draft.
--proresmov only: proxy, lt, 422, hq, 4444 (default). Refused on other formats rather than silently ignored.
--transparentForce 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.
--jsonOne 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 Admiral

Columns 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.

    CodeMeaning
    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 2 immediately — a typo does not cost a GPU boot to discover. A silent composition passed to captions is 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 1 with 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 --log to see output. A packaged Windows app has no console attached, so a run from cmd or PowerShell gets the exit code and nothing else. --log render.log mirrors 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.
Last updated on