> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fjall.io/llms.txt
> Use this file to discover all available pages before exploring further.

# fjall dev

> Create, list and tear down ephemeral Fjall dev environment slots on AWS, with one preview slot per git branch.

`fjall dev` manages ephemeral dev-environment slots. Each slot is one branch's preview environment, running on a shared per-application substrate (a database, a load balancer and dev DNS).

<Accordion title="Prerequisites">
  * **Signed in.** Every `dev` subcommand authenticates first. Run `fjall login`.
  * **An application registered with Fjall.** The `<app>` argument resolves to an application in your organisation.
  * **A dev substrate in `ready` state for that application.** `fjall dev up` reads the substrate to learn which ECR repository to push to. A substrate that is `creating`, in `error`, or absent fails the command before any build starts.
  * **Docker running locally, plus a Dockerfile.** `fjall dev up` builds the branch image on your machine and pushes it.
  * **A git checkout**, or pass `--branch <name>`. Outside a git repository with no flag, the command stops and asks for `--branch`.
</Accordion>

## Manage dev slots

```bash theme={null}
fjall dev up <app>
fjall dev list <app>
fjall dev down <app>
fjall dev substrate down <app>
```

| Subcommand                 | What it does                                                |
| -------------------------- | ----------------------------------------------------------- |
| `dev up <app>`             | Build, push and spin up a dev-environment slot for a branch |
| `dev list <app>`           | List an application's dev-environment slots                 |
| `dev down <app>`           | Tear down the dev-environment slot for a branch             |
| `dev substrate down <app>` | Tear down the application's shared dev substrate            |

Bare `fjall dev` and bare `fjall dev substrate` print help.

```bash theme={null}
# Spin up a slot for the branch you have checked out
fjall dev up api

# Name the slot explicitly
fjall dev up api --branch feature-search

# Build a monorepo service on a non-default port
fjall dev up web --context services/web --port 8080

# Pass runtime configuration to the slot container
fjall dev up api --env LOG_LEVEL=debug --env FEATURE_FLAGS=search,billing

# Run migrations and seed data as the slot starts
fjall dev up api --migration-command "npx prisma migrate deploy" --seed-command "npm run seed"

# See what is running
fjall dev list api

# Tear this branch's slot down
fjall dev down api --branch feature-search
```

## What Happens

### `fjall dev up`

1. Reads the application's dev substrate. The substrate must report `ready` with an account, a region and a slot repository, otherwise the command fails with the substrate's current status.
2. Mints short-lived dev-deploy credentials for the substrate's AWS account.
3. Probes the slot ECR repository before building, so a substrate torn down outside Fjall fails immediately instead of minutes later at the push.
4. Builds the image from `--context` using `--dockerfile`, then pushes it to the slot repository.
5. Creates the slot record with the resulting image tag, container port, health-check path, migration command, seed command and environment variables.
6. Polls the slot until it becomes `active`, then prints its URL.

The image tag is derived from the branch name with a 7-character commit sha appended, for example `feature-search-a1b2c3d`. Characters outside `[a-zA-Z0-9._-]` become hyphens, a leading `.` or `-` is stripped, and the tag is bounded to 128 characters with the sha suffix preserved.

If the build context holds a `prisma/migrations` directory, `fjall dev up` derives the expected schema-version variables from the latest migration and reports which keys it added. Your own `--env` values win on the same key.

### Warnings you may see

| Condition                                                | Warning                                                                                                                 |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `--branch` names a branch other than the one checked out | The flag labels the slot, and the image still comes from the checked-out branch. Nothing is fetched or checked out.     |
| Uncommitted changes in the build context                 | The tag names a commit, but the image is built from your working tree, so nobody else can rebuild it.                   |
| An `--env` value looks like a credential                 | Use `fjall secrets` instead. Slot `--env` values persist in plaintext in the slot record and task-definition revisions. |

### Waiting and slot status

Slot statuses are `creating`, `active`, `idle`, `waking`, `destroying`, `destroyed` and `error`. `active` ends the wait successfully. `error` and a mid-flight teardown end it as a failure. Any other status keeps polling.

`fjall dev up` polls every 5 seconds for up to 30 minutes and tolerates 3 consecutive network failures. After 60 seconds it notes that an idle substrate resumes its paused database on demand and a cold first boot can take around 10 minutes. After 15 minutes it reminds you that provisioning continues server-side, so you can stop waiting and run `fjall dev list <app>` later. A timeout reports the wait budget, not a lost slot.

### `fjall dev list`

Prints one row per slot with `STATUS`, `BRANCH`, `URL` and `ID`, followed by a count. It queries the Fjall control plane only and changes nothing. A Fjall server that predates dev environments produces a notice and exit code 0 rather than an error.

### `fjall dev down`

Resolves the branch from `--branch` or the current git branch, finds that branch's live slot and destroys it. No matching slot is treated as success with a notice, so repeat runs are safe.

### `fjall dev substrate down`

Destroys the shared substrate behind every slot for the application. It refuses while slots are still live, and points you at `fjall dev down` or `--force`. On success it lists the residual AWS resources that survive the teardown, with a cleanup hint for each. The teardown poll budget is 45 minutes.

<Warning>
  `fjall dev substrate down --force` tears down live dev slots along with the substrate. Every slot database dies with the shared cluster, including your teammates' slots.
</Warning>

### Dry runs and agent mode

There is no dry-run flag on `fjall dev`. `fjall dev list` is the read-only surface, so check it before a teardown.

With `--agent`, each subcommand prints a single JSON result instead of streaming progress. Git-hygiene warnings from `dev up` ride the result object. `fjall dev list --agent --fields` selects from `id`, `slotKey`, `branch`, `status` and `host`, and an invalid selection fails before the authentication round-trip.

## Options

### `fjall dev up <app>`

| Flag                         | Description                                                                                | Default                |
| ---------------------------- | ------------------------------------------------------------------------------------------ | ---------------------- |
| `--branch <name>`            | Branch to spin up                                                                          | Current git branch     |
| `--port <number>`            | Container port the slot task listens on                                                    | `3000`                 |
| `--context <dir>`            | Docker build context directory                                                             | Current directory      |
| `--dockerfile <path>`        | Dockerfile path                                                                            | `<context>/Dockerfile` |
| `--health-check-path <path>` | HTTP path the slot's health check probes                                                   | Omitted when unset     |
| `--migration-command <cmd>`  | Command the slot runs to apply database migrations                                         | Omitted when unset     |
| `--seed-command <cmd>`       | Command the slot runs to seed its database                                                 | Omitted when unset     |
| `--env <KEY=VALUE>`          | Environment variable for the slot container. Repeatable, and overrides auto-derived values | None                   |

Each `--env` token splits on the first `=`, so a value containing `=` survives intact. `--env FLAG=` sets an empty value. A bare `KEY` with no `=` fails the whole command, and no slot is created.

### `fjall dev list <app>`

Takes the shared flags only.

### `fjall dev down <app>`

| Flag              | Description                    | Default            |
| ----------------- | ------------------------------ | ------------------ |
| `--branch <name>` | Branch whose slot to tear down | Current git branch |

### `fjall dev substrate down <app>`

| Flag      | Description                                              | Default |
| --------- | -------------------------------------------------------- | ------- |
| `--yes`   | Confirm the teardown without prompting. Required off-TTY | Off     |
| `--force` | Also tear down live dev slots riding the substrate first | Off     |

`--yes` and `--force` are separate on purpose. `--yes` confirms a plain teardown, which still refuses while slots are live. `--force` takes those slots down with the substrate. A non-TTY session, or `--non-interactive`, never auto-accepts, so scripted teardowns pass `--yes` deliberately.

### Shared flags

Available on `dev up`, `dev list`, `dev down` and `dev substrate down`.

| Flag                | Description                                     |
| ------------------- | ----------------------------------------------- |
| `--non-interactive` | Force plain CLI output (no UI)                  |
| `-v, --verbose`     | Enable verbose output                           |
| `--agent`           | Enable agent output mode                        |
| `--budget <level>`  | Output budget: minimal, compact, or token count |
| `--fields <fields>` | Select exactly these output fields              |
| `--full`            | Disable content truncation                      |

The `dev` and `dev substrate` group commands themselves accept `--non-interactive` and `-v, --verbose`.

## Next Steps

<CardGroup cols={2}>
  <Card title="fjall deploy" icon="rocket" href="/cli/deploy">
    Promote a branch to a real environment once the slot looks right.
  </Card>

  <Card title="fjall secrets" icon="key" href="/cli/secrets">
    Store credentials properly instead of passing them as slot `--env` values.
  </Card>

  <Card title="fjall build" icon="hammer" href="/cli/build">
    Build and push application images outside the dev-slot flow.
  </Card>

  <Card title="Agent mode" icon="robot" href="/cli/agent-mode">
    Drive `fjall dev` from an AI agent with JSON output and field selection.
  </Card>
</CardGroup>
