CLI
Every kinetograph command, with its arguments, options, output and exit codes.
npx kinetograph <command> [entry] [options]
npx kinetograph <command> --helpThe entry is a .tsx, .ts, .jsx or .js project file, a .json scene, or an HTML page (its index.html, or the directory that holds it). HyperFrames projects are HTML pages and render as they are. See HyperFrames projects.
Shared behaviour
--jsonprints one JSON object on stdout instead of text. Progress goes to stderr, which stays quiet with--jsonexcept for the update notice below. A failure prints{ "error": { "code", "message" } }.- Once a day the CLI checks npm for a newer
kinetographand looks for installed agent skills older than the CLI. It prints one line on stderr, and adds anoticesarray to the--jsonresult. It never installs anything.CIorKINETOGRAPH_NO_UPDATE_CHECK=1turns it off. --helpor-hprints a command's usage.kinetograph --helplists the commands.kinetograph --versionor-vprints the package version.- Exit code 0 is success. Exit code 1 is an error, or a failed check:
checkwith type errors,lintwith errors,snapshotwith a mismatch.
Without -o, still, strip, onion and render write under out/ in the project folder (the folder of the nearest package.json): out/stills/, out/sheets/ and out/renders/, named after the composition.
Commands that open a project take two more options. These are still, render, strip, onion, inspect, lint, bench, audio analyze, snapshot and doctor.
| Option | Meaning |
|---|---|
--comp <id> | The composition to use. The default is the first one. |
--props <json> | Input props as a JSON object. See Authoring. |
Frames and ranges
A frame is a whole number from 0. A range is written a..b.
10..40is frames 10 to 39.10..=40is frames 10 to 40...40starts at 0.10..runs to the last frame.--framestakes a comma-separated list, such as0,30,60.
init
Creates a project folder with a starter title card.
npx kinetograph init [dir] [--html]It writes src/index.tsx, src/scenes/Title.tsx, package.json, tsconfig.json and .gitignore, and makes the src/, public/ and out/ folders. With --html it writes html/index.html instead of the TSX files. dir defaults to the current folder. Files that already exist are skipped, never overwritten. It does not run npm install.
add
Installs a component, template or taste from the Kinetograph registry into the project.
npx kinetograph add <name...> [--overwrite] [--yes] [--dir <folder>]
npx kinetograph add --list [--type component|template|taste]Components go to src/components/<name>/, templates to src/templates/<name>/, tastes to src/tastes/<name>/, and their pictures, fonts and audio to public/<kind>/<name>/. Items an item depends on are installed first. A file that already exists is skipped and reported; --overwrite replaces it. If the item needs npm packages the project lacks, the command shows them and asks before installing (--yes skips the question; with --json or no terminal it only prints the install command). Run it inside a project made by init. An item that is not published yet says so and installs nothing.
compositions
Lists the compositions in a project, with size, frame rate and length.
npx kinetograph compositions <entry>still
Renders one frame to a PNG.
npx kinetograph still <entry> <frame> [-o <output.png>] [options]| Option | Meaning |
|---|---|
-o, --output <path> | The PNG to write. The default is out/stills/<comp>-f<frame>.png. |
--strict | Fail on the first frame with content the engine cannot draw. See What works. |
--dev-react | Use React's development build. It prints React's warnings and is slower. |
--preferred-effect-backend <name> | The backend @remotion/effects tries first: webgpu, webgl2 or 2d. See Remotion effects. |
--comp, --props | See above. |
render
Renders frames to a video with audio.
npx kinetograph render src/index.tsxFor a HyperFrames page, render first downloads what the page loads from the web. Add --offline to skip that step. A directory that holds the index.html works too.
The general form is:
npx kinetograph render <entry> [-o <output.mp4>] [options]| Option | Meaning |
|---|---|
-o, --output <path> | The video to write. The default is out/renders/<comp>.mp4. The extension sets the container: .mp4, .mov, .webm or .gif. |
--range <a..b> | The frames to render. The default is all of them. |
--draft | Half size, for a quick look. Same as --scale 0.5. |
--scale <n> | Size multiplier, above 0 and at most 8. Each side rounds down to an even number. |
--concurrency <n> | Frames drawn at once. The default is half the cores, at most 4. 1 uses the main thread. |
--codec <name> | h264 (default), h265, prores, vp9 or gif. A .webm path defaults to vp9, and a .gif path to gif. |
--encoder <name> | An ffmpeg encoder to use in place of the default: libx264 for H.264 and libx265 for H.265 on every platform. See below. |
--crf <n> | Constant quality, lower is better. 0 to 51 for h264 and h265, 0 to 63 for vp9. Not with --video-bitrate. |
--video-bitrate <rate> | A bit rate, such as 8M or 2500k. Not with --crf. |
--pixel-format <name> | yuv420p (default), yuv422p, yuv444p, yuv420p10le, yuv422p10le or yuv444p10le. |
--prores-profile <name> | With --codec prores: proxy, light, standard, hq (default), 4444 or 4444-xq. |
--audio-codec <name> | aac (default for .mp4 and .mov), opus (.webm) or pcm (.mov). |
--audio-bitrate <rate> | Total audio bit rate, such as 320k. The default is 96 kbit/s per channel. Not for pcm. |
--every-nth-frame <n> | With --codec gif. Draws every nth frame and keeps the length. |
--strict | Fail on the first frame with content the engine cannot draw. No output file is left. |
--dev-react | Use React's development build. |
--preferred-effect-backend <name> | See still. |
--comp, --props | See above. |
A bad combination of export flags is refused before bundling, and the message names the flag to change.
Choose an encoder
The built-in ffmpeg handles decoding and its own encoders. An encoder it lacks runs in a separate ffmpeg program: the one in the platform package, or the one KINETOGRAPH_FFMPEG names, then an ffmpeg on your PATH that has libx264. Name h264_videotoolbox or hevc_videotoolbox for the Mac's hardware encoders.
To use your system ffmpeg, set KINETOGRAPH_FFMPEG=$(which ffmpeg). This gives you libx264, and on Intel and AMD GPUs under Linux h264_vaapi, hevc_vaapi, h264_qsv and hevc_qsv (see What works). Licences are under FFmpeg licence.
strip
Writes a contact sheet of evenly spaced frames, labelled with frame number and time.
npx kinetograph strip <entry> -n 12 [-o <sheet.png>] [options]| Option | Meaning |
|---|---|
-n, --count <n> | Number of frames. The default is 12, the most is 64. |
-o, --output <path> | The PNG to write. The default is out/sheets/<comp>-strip.png. |
--range <a..b> | The frames to sample. The default is the whole composition. |
--cols <n> | Columns. The default is 4 for landscape and 6 for portrait. |
--strict | See still. |
--preferred-effect-backend <name> | See still. |
--comp, --props | See above. |
onion
Blends frames of a range over one another, to show a motion path.
npx kinetograph onion <entry> <a..b> -n 6 [-o <onion.png>] [options]| Option | Meaning |
|---|---|
<a..b> | Required. The range to blend. |
-n, --count <n> | Number of frames to blend. The default is 6, the most is 64. |
-o, --output <path> | The PNG to write. The default is out/sheets/<comp>-onion.png. |
--preferred-effect-backend <name> | See still. |
--comp, --props | See above. |
inspect
Prints the scene graph at one frame: each layer's id, type, bounds, effects, and text or file. With --json you get the full graph.
npx kinetograph inspect <entry> --frame 30| Option | Meaning |
|---|---|
--frame <n> | The frame. The default is 0. |
lint
Checks a project at a few frames. It reports overflowing text, layers off the canvas, overlapping text, missing fonts and assets, type errors, and content the engine cannot draw. Each finding names its rule, layer and frames.
npx kinetograph lint <entry> --frames 0,30,60| Option | Meaning |
|---|---|
--frames <list> | Frames to check. The default is 8 frames spread over the composition. |
Exit code 1 means at least one error. Warnings do not change it.
check
Runs tsc --noEmit with the nearest tsconfig.json. It catches misspelled props, which otherwise render without an error.
npx kinetograph check <entry>There are no options. A scene file, or a JavaScript project without a tsconfig.json, has nothing to check.
bench
Times each stage of drawing a frame in milliseconds: js, stringify, handoff, resolve, raster, composite, readback and total.
npx kinetograph bench <entry> --frame 30 --runs 10
npx kinetograph bench <entry> --range 40..90| Option | Meaning |
|---|---|
--frame <n> | The frame to time repeatedly. The default is 0. |
--runs <n> | Timed runs after warm-up. The default is 10. |
--range <a..b> | Times each frame of the range once. Replaces --frame and --runs. |
bench uses React's development build unless NODE_ENV is set. For the production build, run NODE_ENV=production npx kinetograph bench ....
audio analyze
Mixes the project's audio and measures it: integrated loudness (LUFS), true peak (dBTP), clipped samples and silences. See Audio.
npx kinetograph audio analyze <entry> --scenes 0..90,90..180| Option | Meaning |
|---|---|
--range <a..b> | Frames to mix and measure. The default is all of them. |
--scenes <list> | Frame ranges to measure on their own, as well as the whole mix. |
snapshot
Compares rendered frames with approved PNGs in a __snapshots__/ folder next to the entry. A file is named like card.Title.f30.png.
npx kinetograph snapshot <entry> --frames 0,30,60
npx kinetograph snapshot <entry> --update| Option | Meaning |
|---|---|
--frames <list> | Frames to compare. The default is the first, middle and last. |
--update | Writes the current renders as the approved PNGs. |
A frame matches when no colour channel is off by more than 2 levels. A mismatch or a missing approved file exits with 1.
effects
Lists every effect with its type, description and fields.
npx kinetograph effectsdoctor
Runs every frame in the range without the GPU and reports what the engine cannot draw, and where. Use it before a long render. See What works.
npx kinetograph doctor src/index.ts --range 0..120| Option | Meaning |
|---|---|
--range <a..b> | Frames to check. The default is all of them. |
With no entry, doctor checks your install:
npx kinetograph doctorIt prints the Node version, the platform, whether the addon loaded, and which renderer draws (renderer). It also reports the CLI version against the latest on npm (cli) and each installed agent skill with its version and whether it is current (skills). If Skia falls back to the CPU, rendererReason (why not the GPU: in the text) says why: the device, the driver and what it lacks.
studio
Opens the local editor in a browser. See Studio.
npx kinetograph studio <entry>| Option | Meaning |
|---|---|
--port <n> | Port to listen on. The default is 3000. 0 picks a free port. |
--host <address> | Address to listen on. The default is 127.0.0.1. |
--no-open | Do not open the browser. |
--props <json> | Input props merged over each composition's defaultProps. A JSON object or a path to a JSON file. |
--agent <command> | The command that starts your coding agent over ACP, for the chat panel. The default is Claude Code, Codex or Gemini CLI, whichever is installed. |
--allow-remote-agent | Keep the agent on when --host lets other computers in. It is off then by default. |
--offline | Never download what a HyperFrames project loads from the web. It must be cached. |
The studio is the @kinetographdev/studio package, which installs with kinetograph. Stop it with Ctrl-C.
The Available list in the Props tab comes from https://kinetograph.dev/api/catalog, cached in ~/.cache/kinetograph/plugin-catalog.json. --offline (or KINETOGRAPH_OFFLINE=1) never asks the site. KINETOGRAPH_CATALOG_URL reads the list from another address.
fetch-deps
Downloads what a project loads from the web (CDN scripts, ES modules, remote pictures, media, Google Fonts) into the local cache. It pins each file in kinetograph.lock.json beside the entry.
render, still, doctor and studio do this first on their own. Run fetch-deps to do it ahead of time, such as in CI. With --offline on those commands, a file that is not cached is an error.
npx kinetograph fetch-deps src/index.ts --updateFor a Remotion project, fetch-deps fetches the remote pictures and videos its bundle names. Only --update applies. --allow-host, --url and --max-media-mb are for HyperFrames pages.
| Option | Meaning |
|---|---|
--allow-host <host> | Also download from this host (comma-separated for several). By default only cdn.jsdelivr.net, unpkg.com, cdnjs.cloudflare.com and esm.sh. |
--url <url> | Also download this URL (comma-separated for several). Use it for a file the script scan missed. doctor names the ones a render refused. |
--update | Download everything again and rewrite the lock file, to accept a file that changed upstream. |
--max-media-mb <n> | The most megabytes of one remote video or audio file. The default is 500. |
mcp
Runs the MCP server on stdio. It has one tool for each command except studio. See Use with agents.
npx kinetograph mcpExport options
The render codec and quality options follow Remotion's names. The defaults are:
- H.264:
crf 18with the software encoder (libx264). libopenh264 and the hardware encoders get a bit rate instead. VideoToolbox on macOS is opt-in with--encoder h264_videotoolboxand uses 0.2 bits per pixel per frame. - libx264, libx265 and VP9 keep their own keyframe interval. Encoders that would take FFmpeg's 12 frames (VideoToolbox, OpenH264, hardware encoders) write one every 2 seconds.
- VP9:
crf 30. H.265:crf 28. - Audio: 96 kbit/s per channel.
--crf does not apply to prores or gif. The encoder choice for each codec is in AUTHORING.md, section 9.