> From the [Strife developer docs](https://strife.app/docs/reference/cli). Every page is listed in [llms.txt](https://strife.app/docs/llms.txt).

# CLI

The Strife CLI (@strifeapp/cli) connects a local project to Strife: sign in, link a team, define content types in code, and deploy them — from the command line or as part of CI.

Strife CLI is the code-first bridge between your project and Strife. It handles authentication, links a local project to a team, and deploys a code-defined content model to that team's templates — no manual template setup in Strife Studio required.

> [!NOTE]
> **Status:** the CLI is in active development (`0.x`, alpha). The surface area described here is stable enough for day-to-day use, but may still change between minor versions. Pin an exact version in CI.

At a glance, the CLI lets you:

* Authenticate via a browser-based device flow (`strife login`) — no passwords or API keys typed into a terminal.
* Link a local project to a specific team (`strife link`), or bootstrap a brand-new project end to end in one step (`strife` / `strife .`).
* Define content types in TypeScript or JavaScript using [`defineType`](https://strife.app/docs/reference/cli/schemas.md) instead of building templates by hand in Strife Studio.
* Generate local TypeScript types for your content model (`strife typegen`) — see [Typegen](https://strife.app/docs/reference/cli/typegen.md).
* Deploy your code-defined schema as real templates, ready to edit in Strife Studio (`strife push`).
* Upload media directly to a team's asset library (`strife upload`).

See [Commands](https://strife.app/docs/reference/cli/commands.md) for the full command reference, [Schemas](https://strife.app/docs/reference/cli/schemas.md) for `defineType`/`defineConfig`, [Typegen](https://strife.app/docs/reference/cli/typegen.md) for generated types, and [Authentication & Linking](https://strife.app/docs/reference/cli/authentication-and-linking.md) for how sign-in and project linking work under the hood.

## Requirements

* Node.js 22 or later.
* An ESM-compatible project (`"type": "module"` in `package.json`, or ESM-flavored config files). The CLI itself is published as ESM.

The CLI does not assume any particular frontend framework. Everything in this section — authentication, linking, schema authoring, `push`, `typegen` — is plain Node.js tooling that works the same way regardless of what renders your site.

## Install

Add the CLI and the Strife SDK to your project as dev dependencies:

```sh
npm install --save-dev @strifeapp/cli @strifeapp/strife
```

> [!NOTE]
> `strife push` and `strife typegen` always resolve their schema/type-generation implementation from **your project's own installed `@strifeapp/strife`** — not a copy bundled with the CLI — the same way the vite/astro CLIs use your project's installed framework rather than a bundled copy. This holds regardless of whether you use live-preview: `@strifeapp/strife` is required for `push`/`typegen` to run at all, not just for runtime/live-preview integrations.
>
> `@strifeapp/strife/schema` already re-exports everything `@strifeapp/schema` provides (`defineType`, `fields`, `defineConfig`, `glob`), so there's normally no reason to add `@strifeapp/schema` as its own direct dependency — import from `@strifeapp/strife/schema` and let `@strifeapp/strife` pull it in transitively. If `@strifeapp/strife` is missing (for example, a project that installed only `@strifeapp/schema`), `push`/`typegen` fail immediately with a clear "Could not resolve `@strifeapp/strife`" error.

Install the CLI as a **dev dependency**, not globally. Global installs work too, but every command in this documentation uses `npx strife ...`, which finds your project's locally installed binary regardless of whether a global install also exists — the portable form to use in scripts, CI, and instructions you hand to teammates. A bare `strife` (no `npx`) only works if the CLI happens to be installed globally on that specific machine.

## Quickstart

```sh
# 1. Authenticate — prints a URL to open (does not launch a browser for you)
npx strife login

# 2. Link this directory to a workspace + team
npx strife link

# 3. Declare a content type
mkdir schemas
cat > schemas/article.ts <<'EOF'
import { defineType, fields } from '@strifeapp/strife/schema';

export const article = defineType({
  name: 'articles',
  title: 'Article',
  type: 'document',
  fields: {
    heading: fields.text({ label: 'Heading', localizable: true }),
    body: fields.html({ label: 'Body' }),
  },
});
EOF

# 4. Point the CLI at your schema files
cat > strife.config.ts <<'EOF'
import { defineConfig, glob } from '@strifeapp/strife/schema';

export default defineConfig({
  schema: glob('./schemas/**/*.ts'),
});
EOF

# 5. Deploy it
npx strife push
```

After `push` completes, the `Article` type is a real, editable template in Strife Studio.

## Bootstrapping a brand-new project

If you're starting from scratch rather than adding the CLI to an existing project, running the CLI with no arguments (or `strife .`) drives the whole setup interactively — sign-in, team selection or creation, an optional starter template, and writing the local credentials your app needs to connect to the team's database:

```sh
npm create @strife
# or, if @strifeapp/cli is already installed:
npx strife
```

Both invocations run the exact same logic. `npm create @strife` is a thin wrapper that (optionally) creates a target directory and then delegates straight into it.

What it does, step by step:

1. Signs you in (device flow), unless you already have a valid session.
2. Resolves a team: link to one you already have access to, or create a new one by name. (Skipped if the current directory is already linked.)
3. If the directory is empty and you're in an interactive terminal, optionally scaffolds a starter project — currently Astro-based starters only (tagged `strife-starter` under the `nimble-initiatives` GitHub org, discovered at runtime). If you're adding Strife to an existing project, run this from that project's directory instead: since it isn't empty, the starter prompt is skipped automatically and you go straight to linking.
4. Provisions a database client certificate for the team and writes a single `STRIFE_SECRET` value to `.env`, packing the connection details your app needs at runtime (database URLs, certificate, password). `.env` is added to `.gitignore` automatically.
5. If a starter was scaffolded, runs `typegen generate` and `push` for you and seeds some initial content; otherwise, it's on you to run `strife push` once you've written a schema.

> [!NOTE]
> `strife login`/`link`/`setup` only ever store non-secret linkage info (workspace/team IDs) in `.strife/project.json`, which is safe to commit — it's added to `.gitignore` mainly as a convenience, and contains no credentials. The actual secret lives only in `.env`.

## Troubleshooting

**A bare `strife` command works for me but not for a teammate.** `npm install --save-dev` never puts a binary on your system `PATH` — only in that project's `node_modules/.bin/`. If `strife` (without `npx`) works for you specifically, you most likely also have `@strifeapp/cli` installed globally on your machine from something unrelated. Don't assume teammates have the same global install; use `npx strife ...` in any instructions you hand off, and it will resolve correctly whether or not a global install exists.

For live-preview issues (e.g. the preview panel not loading your local dev server), see [Live preview](https://strife.app/docs/reference/live-preview.md#troubleshooting) — that's general Strife Studio behavior, not specific to the CLI.
