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

# stb dev

> Serve the local StreamBuild UI for one project and target.

Compile a project, connect to its selected ClickHouse target, and serve the packaged web UI and JSON
API until interrupted:

```bash theme={null}
stb dev
stb dev --project-dir examples/orders_demo
stb dev --ui-host 127.0.0.1 --ui-port 8000
```

Open `http://127.0.0.1:8000` by default. `stb dev` accepts the normal project, target, variables, and
ClickHouse connection overrides in addition to:

| Option            | Purpose                                 |
| ----------------- | --------------------------------------- |
| `--ui-host VALUE` | Bind interface; defaults to `127.0.0.1` |
| `--ui-port VALUE` | Bind port; defaults to `8000`           |

The UI combines authored definitions with live warehouse state. Use it to inspect ingestion,
freshness, lineage, pipelines, sources, catalog relations, deployment state, quality results, and
durable run history. For direct-mode projects, the Plan view previews destructive downstream
closures and can launch the same `stb build --auto-approve --events` execution path with the resolved
project context.

## Ingestion metrics

The Sources views keep two different operational signals separate:

* **Kafka lag** is a message count: the broker high-water offset minus the effective consumer
  group's committed offset, summed across partitions.
* **Last arrival** is elapsed time since the newest `_replay_landed_at` value in the ClickHouse
  landing table.

Kafka lag is read from Kafka metadata without joining or consuming from the group. Partition detail
shows the landed, committed, and broker-end offsets alongside per-partition lag. The consumer group
is scoped to the selected target database, matching the group rendered into the ClickHouse Kafka
table. If broker metadata or a required committed offset is unavailable, the UI reports Kafka lag as
unavailable; it never substitutes last-arrival age.

Metadata reads are cached and refreshed outside the `/api/state` request path, so a first load may
briefly show unavailable while the initial read completes.

<Frame>
  <img src="https://mintcdn.com/streambuild-docs/G8qa32LheSoLrSSd/images/ui/plan-dark.png?fit=max&auto=format&n=G8qa32LheSoLrSSd&q=85&s=fcedd6e254827421b2696b6e3bfd4aff" alt="Direct rebuild plan in the StreamBuild development UI" width="1600" height="1000" data-path="images/ui/plan-dark.png" />
</Frame>

## Runs and cancellation

Builds emit durable statement events and a heartbeat every 10 seconds. Runs without a terminal fact
appear as `running`, then `unresponsive` after 45 seconds without a signal, and `presumed failed`
after 10 minutes. These are derived display states, not persisted outcomes, and can reverse when a
later heartbeat or terminal event arrives.

<Frame>
  <img src="https://mintcdn.com/streambuild-docs/G8qa32LheSoLrSSd/images/ui/runs-dark.png?fit=max&auto=format&n=G8qa32LheSoLrSSd&q=85&s=38a5450a8aa2e088718ca7fd64973af3" alt="StreamBuild run history with success, failure, and cancelled outcomes" width="1600" height="1000" data-path="images/ui/runs-dark.png" />
</Frame>

The dev server can gracefully cancel only the build child process it launched. If graceful
cancellation does not finish, the UI can force-stop that owned child. Builds started in another
terminal and orphaned runs remain visible but cannot be signalled by the current server. Recovery is
always a fresh `stb build` invocation, never resume.

`stb dev` is a local development surface, not a multi-user control plane. Keep the default loopback
binding unless you intentionally provide network access controls.
