Skip to content

The nola CLI

The nola executable is part of the nola-lang dev dependency. Run commands with npx nola-lang <command> or through your project’s npm scripts.

Use nola <command> --help to see a command’s flags. Flags apply only to the command that defines them. Commands exit with 0 on success and 1 on failure, with errors written to stderr. Running nola without a command, or with --help, prints the command list; an unknown command prints the list and exits with 1. Use --version to print the installed version.

Within a Nola project, npx nola-lang uses the locally installed package. Elsewhere, npx downloads it. Keep the -lang suffix: npx nola can resolve an unrelated package outside a project. To create a new project, use npm create nola.

Terminal window
nola init [dir] [--template <t>|--add] [--provider <id>] [--ide vscode|none] [--agents <list>]
nola build [dir] [--out <dir>]
nola run <entry>
nola check [dir]
nola console [--port <n>]
nola declarations [dir] [--watch]
nola skill install [--agents <list>] [--force]
nola key [--print]
nola login
nola logout
nola account
Terminal window
nola init [dir] [--template <name> | --add] [--provider nola|openai|anthropic|google|typesafe|none] [--ide vscode|none] [--agents claude,universal,agents-md|all|none]

Creates a project or adds Nola to an existing one, using the same flow as npm create nola.

Flag Effect
--template <name> Selects a template. See the template list below.
--add Adds Nola to dir by writing nola.config.ts and merging dependencies into package.json. Cannot be combined with --template. See Add Nola to an existing project.
--ide vscode|none Writes .vscode/launch.json and .vscode/extensions.json by default. Use none to skip them.
--agents <list> Selects agent skill files. Defaults to claude,universal; none skips them. See nola skill install below.
--provider <id> Selects nola, openai, anthropic, google, typesafe, or none.
--trial / --no-trial Shorthand for --provider nola / --provider none.

The first template menu offers:

  • feature-extraction, the default: one .tsi file that extracts typed data with a top-level ask.
  • function-calling: one .tsi file that uses ask to call an async function from a neighboring TypeScript file.
  • agent-loop: one .tsi file with a top-level while loop around an ask, and a context statement read again on every pass.
  • typescript-interop: an infer function imported from plain TypeScript.
  • triage-ticket: a single-file example using typesafe(). Its provider is preselected, and the setup instructions ask you to set TYPESAFE_API_KEY.
  • empty: configuration files and a stub src/main.tsi for a project whose code you write yourself.

The first four run offline with their default configuration. More examples… opens a second menu with file-ticket, extract-resume, extract-invoice, classify-message, chain-of-thought, and research-notes. You can pass any of these names to --template.

Every template except empty is one of the examples in the Nola repository. The scaffolder copies it from the release tag that matches its own version, falling back to main when the tag is missing, so scaffolding those templates needs network access. empty ships inside the package and works offline.

After you select a template, the interactive flow asks for an inference provider, with nola: dev highlighted. The Nola provider configures model: "nola", writes NOLA_API_KEY to .env, and ensures .env is ignored by git. A machine that has not used its anonymous trial receives 25 free runs.

If the trial was already issued, selecting Nola opens the browser sign-in flow before the remaining setup steps. The menu says Trial key already issued. Get another? Enter to sign in. A failed sign-in returns to the menu. If you are already signed in, the menu indicates that, and the key is created on your account.

Other providers write their configuration and an API-key placeholder in .env.example:

Provider Model configuration Environment variable
openai openai("gpt-5-mini") OPENAI_API_KEY
anthropic anthropic("claude-sonnet-4-5") ANTHROPIC_API_KEY
google google("gemini-2.5-flash") GEMINI_API_KEY
typesafe typesafe() TYPESAFE_API_KEY

Copy the placeholder to .env and supply your key. The typesafe.ai option includes a warning for templates with unsupported types: it accepts literal unions and booleans, and rejects unsupported output types before a network request.

--provider none keeps the template’s configuration, including offline replay where provided. It is the default for non-interactive runs. If a non-interactive run requests Nola on a machine that has used its trial and has no saved sign-in, no key is issued; the output directs you to nola login.

Terminal window
nola build [dir] [--out dist]

Compiles every .tsi under dir, which defaults to ., into the output directory, which defaults to dist. It skips node_modules, .git, and dist, and preserves the source directory structure. For example, src/person.tsi produces dist/src/person.tsi.js, its source map, and a .tsi.d.ts declaration file.

For app projects, build.target: "app" is the default. The build bundles nola.config.ts into dist/nola.config.js and adds an import to each built module so the app configures itself. It refuses to overwrite a dist/nola.config.js that Nola did not generate. Library builds with build.target: "lib" skip this configuration step.

Views of plain TypeScript modules are emitted as .tsi.js and .tsi.d.ts files beside the built output. nola build does not compile the underlying .ts files; see Deploying for how to include them.

Terminal window
nola run <entry>

Runs a .ts or .tsi entry point with the Nola loader registered for its directory. The loader compiles .tsi in memory and loads nola.config.ts and its neighboring .env.

This is a shortcut for node --import nola-lang/register <entry>. Like node, it exits when the program’s event loop drains, so a trace still on its way to the console arrives before the process ends, and a program that keeps a server open keeps running. If the program fails, nola run still gives traces already on their way up to two seconds to arrive, then exits with code 1. Scaffolded projects use it for npm start. See The Node loader.

Terminal window
nola check [dir]

Type-checks both the compiled .tsi code and the project’s TypeScript files, using tsconfig.json. Diagnostics point back to the original .tsi positions, in the form file:line:col NOLA… or TS….

Nola compile errors (NOLA1xxx and NOLA2xxx) are reported first. Use this command to check Nola source; plain tsc cannot parse .tsi.

Terminal window
nola console [--port <n>]

Starts the local Nola Console for viewing ask traces. It listens only on loopback, using the first available port from 4141 upward. Pass --port to require a specific port. One console instance can receive traces from all projects on the machine.

The console stores traces in ~/.nola/console using Node’s built-in SQLite database, which requires Node ≥ 22.13. On startup, it prints the URL and storage directory. It then prints one line per event, including the time, event kind, source site, provider, and duration. Events include ask start and end, provider requests and replies, validation failures, retries, and invocation end.

To connect a project, set telemetry: "<url>" in nola.config.ts using the printed URL. This is shorthand for nola.tracer("<url>"). Add terminalTrace() to the telemetry list if you also want terminal traces. See Telemetry.

Clear traces, below the trace list, deletes all stored traces, asks, and ask definitions and prints a clear line. New events continue to arrive. Press Ctrl+C to stop the console. Trace delivery is asynchronous, so inference continues even when the console is unavailable.

Terminal window
nola declarations [dir] [--watch]

Writes <name>.d.tsi.ts beside each .tsi file. These declarations let plain tsc and framework builds resolve .tsi imports when "allowArbitraryExtensions": true is set.

Use --watch to regenerate declarations as .tsi files change; press Ctrl+C to stop it. Add the generated files to .gitignore. The editor hides them when the source .tsi is present, and nola check ignores them. Nola’s bundler plugins can generate them during a build.

Terminal window
nola skill install [--agents claude,universal,agents-md | all | none] [--force]

Installs Nola instructions for coding assistants in the project. Each copy is self-contained and stamped with the nola-lang version that wrote it.

Target Files written
claude .claude/skills/nola/. When universal is also selected, this is a relative symlink to that copy. Otherwise, it is a separate copy.
universal .agents/skills/nola/, the shared Agent Skills location used by compatible coding assistants.
agents-md The skill body embedded in AGENTS.md.

Interactive runs preselect claude and universal. Non-interactive runs must pass --agents. Scaffolding and --add install both by default; --agents overrides that choice.

Copies stamped with the installed version are left alone. Older copies are reported as stale and replaced only with --force, so run nola skill install --force after upgrading. With the universal target, --force also removes superseded, Nola-generated .cursor/rules/nola.mdc and .github/instructions/nola.instructions.md files. Files without Nola’s generation stamp are left alone.

On Windows, a git checkout without symlink support may leave a plain file where the Claude skill link should be. Running nola skill install repairs it. Creating a symlink requires Developer Mode or an elevated shell; otherwise, the installer writes a copy and reports that choice.

You can also install the skill through the community Agent Skills CLI: npx skills add nola-lang/nola uses the public repository, while npx skills experimental_sync finds it in an installed nola-lang project’s dependencies. These copies have no Nola version stamp, so nola skill install reports them as externally installed and leaves them alone.

Terminal window
nola key
nola key --print

Gets a Nola API key and offers to save it in the current project’s .env.

  • If you are signed in, the key is created on your account.
  • If this machine has not used its free trial, it receives an anonymous trial key.
  • If the machine has used its trial, the command asks you to sign in. Yes is selected by default. Choosing No or pressing Esc exits with 1 without opening the browser.

The output includes the new key and whether it was saved:

Key minted on your Nola account.
NOLA_API_KEY=nola_sk_…
Added to .env. Use it with `model: "nola"` in nola.config.ts.

After printing the key, the command asks Add it to .env?, with Yes selected. Enter accepts; the arrow keys change the choice. Esc or Ctrl+C leaves without writing.

If .env already contains NOLA_API_KEY, a second prompt asks whether to replace it, with No selected. Accepting replaces that line; any other response keeps the existing key. Non-interactive runs print Not written — add the line above to .env yourself.

This command changes only .env. For project setup, including .gitignore, configuration, and dependencies, use the scaffold or nola init --add --trial.

With --print, stdout contains only the key. Sign-in messages go to stderr, so NOLA_API_KEY=$(npx nola-lang key --print) works. This mode does not write .env.

An account can have ten live keys. Use the account console to list or revoke them. The command exits with 1 if key creation fails, sign-in is declined or times out, or a non-interactive run needs you to sign in. The error message explains the failure and, when needed, directs you to npx nola-lang login. For development, NOLA_API_URL overrides the API endpoint.

Terminal window
nola login
nola logout

nola login opens a browser to sign this machine in to Nola. It prints the link before opening it:

Sign in to Nola: open https://….auth0.com/authorize?…
Waiting for the browser…
Signed in as you@example.com.

The CLI waits for the browser to return to a local callback on 127.0.0.1, using one of the server-specified ports from 47831–47833. Complete sign-in on the machine running the command. Over SSH, forward the callback port or sign in locally.

Set NOLA_BROWSER to choose the browser command, such as NOLA_BROWSER="firefox". Set NOLA_NO_BROWSER=1 to print the link without opening it.

The session is stored in ~/.nola/credentials.json with owner-only permissions and refreshed automatically. Tokens are not printed or stored in the project.

If this machine used an anonymous trial, sign-in preserves that account’s key and run usage. Subsequent keys are created on the same account. If the current project’s .env contains a trial key from another machine, sign-in links that trial account too and prints Linked this project's trial account to your Nola account.

The command exits with 1 if sign-in is declined, takes longer than five minutes, is unavailable on the server, or returns without a Nola account. In the last case, it reports Sign-in did not return your Nola account — the server's sign-in provider is misconfigured. and stores nothing.

If the server later rejects a saved session, for example with account_claim_missing or account_mismatch, the CLI removes it. Run nola login again to sign in.

nola logout revokes and removes the saved session, then prints Signed out of Nola. If you are already signed out, it reports that instead.

Terminal window
nola account

Shows the signed-in account and opens its console page. The command works from any directory. If you are signed out, an interactive run starts sign-in; a non-interactive run exits with 1 and directs you to nola login.

If the current project’s .env contains a trial key, that trial account is linked first. The command then prints the account status and balance:

Nola account: you@example.com — 3 / 25 free runs used
Balance $7.84

The output also explains that the hosted service is intended for prototyping and development. It opens your account page and prints the link in case the browser does not open. NOLA_NO_BROWSER=1 skips opening the browser. The page signs you in with the same account without putting a key or token in the URL.

The account page shows your balance and API keys, masked to their prefix and last characters. You can add $5, $25, $50, or a custom amount through Stripe, up to a $100 account balance. All keys on the account share its balance and free runs.

Revoking a key stops it from working immediately. Use nola key to create a replacement. Viewing the account does not change project files or existing keys.

The command exits with 1 if the session is invalid or the API cannot be reached. An invalid-session message directs you to nola login. NOLA_API_URL overrides the API endpoint for development.

You can use another provider instead of hosted Nola inference. See Providers. For an existing project, npx nola-lang init --add --no-trial writes configuration without requesting a trial.

npm create nola runs create-nola, an alias for create-nola-lang. The installed nola init command uses the same setup flow and produces the same project.

Next: The Node loader