We use anonymous analytics to improve VanillaSky. No personal data is collected. Learn more

    CLI reference

    The vanillasky CLI validates, renders, and shares VideoConfig JSON with a local Chrome. No cloud, no credits — the same deterministic render contract as the server export path, driven from your machine.

    usage
    vanillasky setup [--check]
    vanillasky render <config.json> [options]
    vanillasky validate <config.json> [--json] [--format <id>]
    vanillasky tracks [--json]
    vanillasky scope [--json]
    vanillasky brand [path] [--json]
    vanillasky link <config.json> [--base <url>]

    setup

    Interactively fills in only what's missing — Pexels key, default orientation, music mood (every prompt skippable, merged into ~/.vanillasky/config.json) — and offers to scaffold a DESIGN.md for the current repo.

    FlagDescription
    --checkPrint the current setup state (config, Pexels key, default orientation, music mood, DESIGN.md) without prompting.

    validate

    Checks structure, template ids (camelCase, with suggestions for near-misses), every scene's variables against the template's variable schema (unknown names, missing required, type mismatches), backgroundEffect placement, and — when the config declares "format": "launch" or --format launch is passed — the slot contract. Exits 1 on errors.

    FlagDescription
    --jsonMachine-readable JSON output.
    --format <id>Enforce a format's slot contract (e.g. launch); defaults to the config's format field when present.

    render

    Full render to MP4 (validates first and refuses invalid configs), or cheap inspection renders: a single frame in ~2 seconds, or a contact sheet per scene.

    bash
    vanillasky render video.json                       # full render → ./video.mp4
    vanillasky render video.json --frame 1.2 --out check.png   # one PNG (~2s)
    vanillasky render video.json --sheet --out ./sheet # 5 PNGs per scene + sheet.png
    vanillasky render video.json --draft               # fast in-browser WebCodecs export
    vanillasky render video.json --fps 30 --scale 0.5 --pages 4 --out out.mp4
    FlagDescription
    --out <path>Output path (default ./video.mp4; --frame → PNG; --sheet → directory).
    --fps <n>Frames per second (default 30).
    --scale <0..1>Resolution scale, 1 = full resolution (default 1; 1080x1920 portrait / 1920x1080 landscape per the config's orientation).
    --frame <sec>Render a single frame at <sec> as a PNG and exit (~2s). Pick a mid-scene time — scene boundaries catch transition blends.
    --sheetContact sheet: 5 evenly-spaced PNGs per scene plus a composited sheet.png.
    --draftFast in-browser WebCodecs export (fixed 30fps, full resolution).
    --pages <n>Parallel browser pages for the full render (default 4).
    --no-validateSkip config validation before rendering.
    --no-design-mdDon't merge DESIGN.md brand tokens (render and validate).
    --no-pexelsDon't auto-resolve mediaKeyword via the Pexels API.
    --openOpen the finished MP4 with the platform viewer (best-effort).
    --base <url>Host for the Watch/Studio links in the completion block (default https://vanillasky.ai).

    tracks

    Lists the bundled audio library — ids, moods, energy, durations, descriptions. Use a track via "audio": { "trackId": "<id>" }. --json for machine-readable output.

    scope

    Prints the exact globals a custom_* scene's componentSource can use — custom source has no imports, everything listed is already in lexical scope. --json for machine-readable output.

    brand

    vanillasky brand [path] shows which DESIGN.md would apply to a directory and the mapped tokens (--json for machine-readable output).

    link

    Prints a zero-install browser-render URL for a config: <base>/render#config=<base64url>. Anyone can watch the video without local Chrome.

    FlagDescription
    --base <url>Host for the render link (default https://vanillasky.ai).

    DESIGN.md brand ingestion

    When the repo root above the config file carries a DESIGN.md — discovered with a git-style upward walk — render and validate merge its front-matter tokens into the config:

    DESIGN.md tokenConfig field
    colors.primarystyle.brandKit.accent
    colors.secondarystyle.brandKit.secondary
    colors.background / colors.surfacestyle.brandKit.bg
    first typography fontFamilystyle.font
    • Precedence: config-explicit values > DESIGN.md > defaults. Opt out with --no-design-md. A malformed file warns and is skipped — it never fails a render.
    • The cwd is only a fallback: it applies only when the config's own directory tree has no DESIGN.md and the config declares no brandKit, and the merge is logged loudly — an unrelated repo's brand never silently bleeds into a branded config.

    Stock footage (Pexels)

    With PEXELS_API_KEY set (free at pexels.com/api; env var, or ~/.vanillasky/config.json { "pexelsApiKey": "..." } — env wins), render resolves scenes with a mediaKeyword and an empty mediaUrl against the Pexels API before validating: orientation-matched, video unless the scene pins mediaType: "photo", best-HD file, and the video thumbnail stored as the sibling mediaPoster. Each fill is logged; responses are cached per keyword within the run.

    Pexels' API guidelines require a prominent link to Pexels wherever the API-sourced media is shown, and encourage crediting the photographer — the CLI logs the photographer for every filled clip so you can carry the credit into your post.

    Requirements

    Node 18+, a Chromium-based browser, and ffmpeg (auto-installed via ffmpeg-static) — see the overview for details. Proxy env vars (HTTPS_PROXY/NO_PROXY) are passed into the browser.