---
title: CLI
url: "https://native-sdk.dev/docs/cli"
docs_index: /llms.txt
lastUpdated: 2026-10-10
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

The `native` CLI provides project scaffolding, markup validation, automation, packaging, and debugging tools. Every verb accepts `--help` (prints usage and exits 0); unknown flags error with the usage text.

## Core loop

### `native init`

```sh
native init [path] [--template <ts-core|zig-core>] [--frontend <native|next|vite|react|svelte|vue>] [--full]
```

Scaffold a new Native SDK project. The default `native` frontend scaffolds a native-rendered markup app with no web frontend and no build files — the CLI owns the build. The default core is TypeScript: `src/core.ts`, `src/app.native`, `app.json`, and no language flag anywhere else — the build detects which core the tree carries. Omit `path` to scaffold into the current directory.

<dl>
  <dt>
    `--template`
  </dt>

  <dd>
    Which core to scaffold:

    `ts-core`

    (default) for

    `src/core.ts`

    , or

    `zig-core`

    for

    `src/main.zig`

    plus generated full-loop tests. Applies to the native frontend only.
  </dd>

  <dt>
    `--frontend`
  </dt>

  <dd>
    What to scaffold:

    `native`

    (default) for a native-rendered markup app, or

    `next`

    ,

    `vite`

    ,

    `react`

    ,

    `svelte`

    ,

    `vue`

    for a web frontend in a WebView shell.
  </dd>

  <dt>
    `--full`
  </dt>

  <dd>
    Also write

    `build.zig`

    ,

    `build.zig.zon`

    , editor config, and CI.
  </dd>
</dl>

### `native dev`

```sh
native dev [dir]
native dev [dir] --core [--script msgs.ndjson] [--watch]
native dev --binary <path> [--manifest app.json] [--url <url>] [--command "<cmd>"] [--timeout-ms <n>]
```

Build and run the app in the current (or given) app directory — a Debug build by default, printing a one-line completion and naming any failing step. The markup hot-reload watcher and the Debug-only diagnostics are compiled in only in Debug; pass `-Doptimize=...` to override. Apps with a frontend dev config also get the managed dev server — see [Dev Server](/docs/cli/dev).

<dl>
  <dt>
    `--core`
  </dt>

  <dd>
    Run the TypeScript core's logic loop under node instead of building the app: dispatch Msgs as JSON lines on stdin, watch the committed model and effect transcript, advance a virtual clock to fire timers. This mode does not render the UI. Use

    `native dev`

    to run the app in a window. See

    <a href="/docs/typescript#the-dev-loop">TypeScript Cores</a>

    .
  </dd>

  <dt>
    `--script`
  </dt>

  <dd>
    With

    `--core`

    : replay a newline-delimited JSON message file instead of reading stdin.
  </dd>

  <dt>
    `--watch`
  </dt>

  <dd>
    With

    `--core`

    : re-run the script on every

    `src/core.ts`

    edit.
  </dd>

  <dt>
    `--binary`
  </dt>

  <dd>
    Path to a prebuilt app binary — the legacy prebuilt-shell form: the build step is skipped and only the frontend dev flow runs. Ordinary

    `native dev`

    builds the app itself.
  </dd>

  <dt>
    `--manifest`
  </dt>

  <dd>
    Path to

    `app.json`

    or

    `app.zon`

    (default: auto-detected, JSON first).
  </dd>

  <dt>
    `--url`
  </dt>

  <dd>
    Override the dev server URL from the app manifest.
  </dd>

  <dt>
    `--command`
  </dt>

  <dd>
    Override the dev server command (space-separated).
  </dd>

  <dt>
    `--timeout-ms`
  </dt>

  <dd>
    Milliseconds to wait for the dev server (default from the app manifest, or 30000).
  </dd>
</dl>

### `native build`

```sh
native build [dir]
```

Build a ReleaseFast binary into `zig-out/bin/`, printing a one-line completion and naming any failing step.

### `native test`

```sh
native test [dir]
```

Run the app's test suite, printing the zig build summary (step/test tally) plus a final `native test: passed` line. It also refreshes the model-contract artifact `native check` reads.

### `native check`

```sh
native check [dir] [--strict]
```

Validate the whole tree without building the app. A TypeScript core (`src/core.ts`) runs the subset checker first — real tsc semantics plus the app-core rules, diagnostics verbatim — then every `src/**.native` markup file and the app manifest are checked as before. With a fresh model contract (`zig-out/model-contract.zon`, refreshed by `native test`) it also checks bindings, iterables, and message tags against your `Model`/`Msg` — for a TypeScript core, against its model contract — and warns on model state no view uses. Without the artifact it degrades to structural checking and says so: "model contract: not yet built - bindings checked structurally only; run `native test` to enable typed checks". Markup accessibility findings are reported per file in full, and a failing `src/*.native` file that no Zig source embeds gets a leftover-file hint.

<dl>
  <dt>
    `--strict`
  </dt>

  <dd>
    Fail on warnings.
  </dd>
</dl>

## App lifecycle

### `native eject`

```sh
native eject [dir]
```

Write an owned `build.zig`/`build.zig.zon` into the app (once); the verbs then drive your files via `zig build`. Ejecting is only for owning the build files — it is never a prerequisite: zero-config apps build, test, and [package](/docs/packaging) directly (`native package` works on the zero-config build as-is).

### `native eject component`

```sh
native eject component <name> [dir]
```

Write an owned copy of a library composite into `src/components/` (once, never overwriting — ejecting again errors with the file to delete first). Ejectable today: `stepper`, `timeline`, `timeline-item` — the library views that are compositions of primitives; engine controls are not on the menu (theme them through [tokens](/docs/theming) instead). TypeScript apps receive Native markup templates through `<import>` and `<use>`; Zig-core apps receive a compatible Zig view when one exists, while components without a Zig form are rejected with a clear message. Each file opens with a header comment walking through the call-site migration, and each builds a widget tree identical to its library form at the moment of ejection. Unknown names get a did-you-mean plus the full ejectable list. See [Building Components](/docs/building-components#use-eject-or-build).

### `native doctor`

```sh
native doctor [--strict] [--manifest app.json] [--web-engine system|chromium] [--cef-dir path] [--cef-auto-install]
```

Check host environment, WebView, manifest, and CEF. See [native doctor](/docs/debugging/doctor) for what each check means.

### `native validate`

```sh
native validate [app.json|app.zon]
```

Validate `app.json` or `app.zon` against the same manifest contract.

### `native package`

```sh
native package [--target <macos|linux|windows|ios|android>] [flags]
```

Package the app for distribution. The manifest is picked up at `app.json` (falling back to `app.zon`) and the binary at `zig-out/bin/<name>` automatically; the flags below override.

<dl>
  <dt>
    `--target`
  </dt>

  <dd>
    Target platform (

    `macos`

    ,

    `linux`

    ,

    `windows`

    ,

    `ios`

    ,

    `android`

    ).
  </dd>

  <dt>
    `--manifest`
  </dt>

  <dd>
    Path to

    `app.json`

    or

    `app.zon`

    .
  </dd>

  <dt>
    `--output`
  </dt>

  <dd>
    Output path for the package.
  </dd>

  <dt>
    `--binary`
  </dt>

  <dd>
    Path to the built binary.
  </dd>

  <dt>
    `--assets`
  </dt>

  <dd>
    Path to frontend assets directory.
  </dd>

  <dt>
    `--optimize`
  </dt>

  <dd>
    Optimization level.
  </dd>

  <dt>
    `--web-engine`
  </dt>

  <dd>
    Temporarily override the app manifest with

    `system`

    or macOS-only

    `chromium`

    .
  </dd>

  <dt>
    `--web-layer`
  </dt>

  <dd>
    Override the app manifest's

    `webview_layer`

    with

    `auto`

    ,

    `include`

    , or

    `exclude`

    — the same precedence as

    `-Dweb-layer`

    in the build graph.

    `zig build package`

    passes the graph's resolved decision here automatically so the package always matches the built executable.
  </dd>

  <dt>
    `--cef-dir`
  </dt>

  <dd>
    Temporarily override the CEF distribution path from the app manifest.
  </dd>

  <dt>
    `--cef-auto-install`
  </dt>

  <dd>
    Temporarily allow prepared CEF installation during Chromium packaging.
  </dd>

  <dt>
    `--signing`
  </dt>

  <dd>
    Signing mode:

    `none`

    ,

    `adhoc`

    , or

    `identity`

    .
  </dd>

  <dt>
    `--identity`
  </dt>

  <dd>
    Code signing identity name.
  </dd>

  <dt>
    `--entitlements`
  </dt>

  <dd>
    Path to entitlements file.
  </dd>

  <dt>
    `--notarize`
  </dt>

  <dd>
    Submit the final macOS artifact to Apple's notary service, then staple and validate the accepted ticket. Requires identity signing.
  </dd>

  <dt>
    `--notary-profile`
  </dt>

  <dd>
    Name of a

    `notarytool`

    Keychain profile created with

    `xcrun notarytool store-credentials`

    .
  </dd>

  <dt>
    `--archive`
  </dt>

  <dd>
    Create a distributable archive. On macOS this is a styled DMG with the app, an Applications alias, a generated or custom background, and the Finder layout declared by the app manifest.
  </dd>
</dl>

### Platform shortcuts

```sh
native package-windows [--output path] [--binary path] [--service-binary path]
native package-linux [--output path] [--binary path] [--service-binary path]
native package-ios [--output path] [--binary path]
native package-android [--output path] [--binary path]
```

Per-platform shortcuts for `native package --target <platform>`.
The desktop shortcuts use an explicit `--service-binary` when supplied; otherwise, service-bearing projects discover the normal `zig-out/bin/<app>_services[.exe]` build output just like the canonical command.

### `native bundle-assets`

```sh
native bundle-assets [app.json|app.zon] [assets] [output]
```

Copy frontend assets into the build output.

## Tooling

### `native markup`

```sh
native markup check <file.native> [more files...] [--strict]
native markup dump <file.native> [--out doc.nsui]
native markup lsp
```

Work with Native markup files directly, outside the app verbs.

<dl>
  <dt>
    `markup check`
  </dt>

  <dd>
    Validate Native markup without building; errors carry

    `file:line:column`

    and a diagnostic message. Run inside an app directory it picks up a fresh model contract the same way

    `native check`

    does;

    `--strict`

    promotes warnings to failures.
  </dd>

  <dt>
    `markup dump`
  </dt>

  <dd>
    Resolve and validate a view, encode the canonical NSUI binary, and print the JSON inspection view derived from the decoded binary;

    `--out`

    also writes the

    `.nsui`

    artifact.
  </dd>

  <dt>
    `markup lsp`
  </dt>

  <dd>
    Run the markup language server (diagnostics, completion, hover) for editor integration.
  </dd>
</dl>

### `native automate`

```sh
native automate <command>
```

Interact with the automation server of a running automation-enabled app. See [Automation](/docs/automation) for the full workflow.

<dl>
  <dt>
    `automate list`
  </dt>

  <dd>
    List running automation-enabled apps.
  </dd>

  <dt>
    `automate snapshot`
  </dt>

  <dd>
    Dump current app state.
  </dd>

  <dt>
    `automate screenshot <view-label> [<scale>]`
  </dt>

  <dd>
    Render a

    `gpu_surface`

    view's canvas to

    `screenshot-<view-label>.png`

    through the deterministic CPU reference renderer.
  </dd>

  <dt>
    `automate reload`
  </dt>

  <dd>
    Reload the WebView.
  </dd>

  <dt>
    `automate resize <width> <height> [<scale>]`
  </dt>

  <dd>
    Dispatch a main-window resize event.
  </dd>

  <dt>
    `automate menu-command <id>`
  </dt>

  <dd>
    Dispatch a menu command event.
  </dd>

  <dt>
    `automate native-command <id> [<view-label>]`
  </dt>

  <dd>
    Dispatch a native view command event.
  </dd>

  <dt>
    `automate widget-action <view-label> <widget-id> <action> [<value>]`
  </dt>

  <dd>
    Invoke a retained canvas widget action.
  </dd>

  <dt>
    `automate widget-click <view-label> <widget-id>`
  </dt>

  <dd>
    Dispatch a pointer click at a retained canvas widget.
  </dd>

  <dt>
    `automate widget-hold <view-label> <widget-id>`
  </dt>

  <dd>
    Press-and-hold a retained canvas widget (drives

    `on_hold`

    ).
  </dd>

  <dt>
    `automate widget-context-press <view-label> <widget-id>`
  </dt>

  <dd>
    Secondary-click a retained canvas widget (context menu, or

    `on_hold`

    when none).
  </dd>

  <dt>
    `automate widget-context-menu <view-label> <widget-id> <item-index>`
  </dt>

  <dd>
    Invoke a widget's declared context-menu item by index — the snapshot lists each widget's items in order.
  </dd>

  <dt>
    `automate widget-drag <view-label> <widget-id> <start-x-ratio> <end-x-ratio> [<start-y-ratio> <end-y-ratio>]`
  </dt>

  <dd>
    Dispatch pointer down/drag/up across a retained canvas widget.
  </dd>

  <dt>
    `automate widget-wheel <view-label> <widget-id> <delta-y> [<delta-x>]`
  </dt>

  <dd>
    Dispatch wheel input at a retained canvas widget; the optional

    `delta-x`

    scrolls the horizontal axis (each axis routes to the nearest region that scrolls it).
  </dd>

  <dt>
    `automate widget-key <view-label> <key> [<text>]`
  </dt>

  <dd>
    Dispatch key input to the focused retained canvas widget.
  </dd>

  <dt>
    `automate widget-pinch <view-label> <scale> [<x> <y>]`
  </dt>

  <dd>
    Dispatch a trackpad pinch gesture at a gpu-surface view (

    `scale`

    is the final multiplicative zoom for the gesture; the anchor point defaults to the view center).
  </dd>

  <dt>
    `automate shortcut <id>`
  </dt>

  <dd>
    Dispatch a shortcut command event.
  </dd>

  <dt>
    `automate tray-action <item-id>`

    /

    `automate tray-action <status-item-id> <item-id>`
  </dt>

  <dd>
    Select a status-item dropdown row; the one-id shorthand targets primary status item

    `#1`

    .
  </dd>

  <dt>
    `automate focus <view-label>`
  </dt>

  <dd>
    Focus a native or WebView-backed view.
  </dd>

  <dt>
    `automate focus-next`

    /

    `automate focus-previous`
  </dt>

  <dd>
    Move focus through visible, enabled views.
  </dd>

  <dt>
    `automate wait`
  </dt>

  <dd>
    Wait for

    `ready=true`

    in the snapshot.
  </dd>

  <dt>
    `automate assert [--absent] [--timeout-ms <n>] <pattern>...`
  </dt>

  <dd>
    Poll the snapshot until every regex pattern matches (or, with

    `--absent`

    , until none match); on timeout, prints the missing patterns plus the snapshot tail and exits non-zero.
  </dd>

  <dt>
    `automate bridge <json>`
  </dt>

  <dd>
    Send a bridge command (origin

    `zero://inline`

    ).
  </dd>
</dl>

### `native skills`

```sh
native skills list
native skills get <name> [--full]
native skills get --all [--full]
```

List and print the built-in AI agent skills the CLI ships — the version-matched content the `npx skills add vercel-labs/native` discovery skill loads from. See [Agent Skills](/docs/skills) for the one-command agent install, what each skill covers, and how to deliver one to an agent.

<dl>
  <dt>
    `skills list`
  </dt>

  <dd>
    List built-in skills served by the installed CLI.
  </dd>

  <dt>
    `skills get <name>`
  </dt>

  <dd>
    Output a skill's content (for example

    `skills get core`

    or

    `skills get native-ui`

    ).
  </dd>

  <dt>
    `skills get --all`
  </dt>

  <dd>
    Output every non-hidden skill.
  </dd>

  <dt>
    `--full`
  </dt>

  <dd>
    Also include a skill's reference and template files when present.
  </dd>
</dl>

### `native cef`

```sh
native cef install|path|doctor [--dir path] [--version version] [--source prepared|official] [--force]
```

Manage the macOS CEF runtime for Chromium-engine apps.

<dl>
  <dt>
    `cef install`
  </dt>

  <dd>
    Download, prepare, and verify the macOS CEF runtime.
  </dd>

  <dt>
    `cef path`
  </dt>

  <dd>
    Print the default or configured CEF directory.
  </dd>

  <dt>
    `cef doctor`
  </dt>

  <dd>
    Check only the CEF layout.
  </dd>
</dl>

<dl>
  <dt>
    `--dir`
  </dt>

  <dd>
    CEF install directory. Defaults to the host platform directory under

    `third_party/cef`

    .
  </dd>

  <dt>
    `--version`
  </dt>

  <dd>
    CEF binary version to download. The default is Native SDK's pinned tested version.
  </dd>

  <dt>
    `--source`
  </dt>

  <dd>
    `prepared`

    or

    `official`

    . Defaults to

    `prepared`

    , which downloads Native SDK's no-CMake runtime from GitHub Releases.
  </dd>

  <dt>
    `--download-url`
  </dt>

  <dd>
    Override the prepared runtime release base URL, or the official CEF host when using

    `--source official`

    .
  </dd>

  <dt>
    `--allow-build-tools`
  </dt>

  <dd>
    Allow the advanced official CEF path to invoke local build tools for

    `libcef_dll_wrapper`

    .
  </dd>

  <dt>
    `--force`
  </dt>

  <dd>
    Redownload and replace the target directory.
  </dd>
</dl>

Core maintainers who need to build CEF before a Native SDK runtime release exists should use `tools/cef/build-from-source.sh`. The CLI's default `native cef install` path remains the no-CMake app-developer path.

### `native version`

```sh
native version
```

Print the native version.

## Environment variables

<dl>
  <dt>
    `NATIVE_SDK_FRONTEND_URL`
  </dt>

  <dd>
    Dev server URL (read by

    `frontend.sourceFromEnv`

    ).
  </dd>

  <dt>
    `NATIVE_SDK_FRONTEND_ASSETS`
  </dt>

  <dd>
    App convention for signaling pre-built assets.
  </dd>

  <dt>
    `NATIVE_SDK_LOG_DIR`
  </dt>

  <dd>
    Override log output directory.
  </dd>

  <dt>
    `NATIVE_SDK_LOG_FORMAT`
  </dt>

  <dd>
    Log format:

    `text`

    or

    `jsonl`

    .
  </dd>
</dl>

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)