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

# Web

> The web app that ships inside the Filament server

The web app ships inside the server binary and serves at its root, `:8080` by
default. It is a client of the [ConnectRPC API](/pages/api-reference/service/introduction)
and nothing else. Every button maps to an RPC you can call yourself, so
anything you do here is scriptable later.

<Frame caption="The Filament web app">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=dec4b70054cdd5b3ed44fe0f5b2fad02" alt="Filament web app in light mode" width="2880" height="1720" data-path="assets/images/filament-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=e342516f1701cfbf168faa41f227d7ce" alt="Filament web app in dark mode" width="2880" height="1720" data-path="assets/images/filament-dark.png" />
</Frame>

Three objects make up the model, and the navbar follows them:

* A **connection** is a configured connector. Credentials plus connection-scoped
  settings, saved once and reused.
* A **pipeline** is a graph of connections. Edges route resources from a source
  to a sink, each carrying a read mode and a write mode.
* A **run** is one execution of a pipeline route, tracked from request to
  verified write.

## Observability

The landing page. Records and bytes moved, run durations, and success rate
over a timeframe you pick, plus a feed of recent runs across every pipeline.
The charts come from the metrics service, which aggregates the same run rows
the rest of the app reads.

<Frame caption="Observability, the landing page">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-observability-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=04e83ae64f657e300e5bee9d342bbe35" alt="Observability dashboard in light mode" width="2880" height="1720" data-path="assets/images/filament-observability-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-observability-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=e8d3032597b59c910809e6c4a149fcee" alt="Observability dashboard in dark mode" width="2880" height="1720" data-path="assets/images/filament-observability-dark.png" />
</Frame>

## Connections

Sources and Sinks each list what you have already connected. A card carries
the connector it uses, how many pipelines depend on it, and its current
version, which is the optimistic lock that keeps concurrent edits from
overwriting each other.

<Frame caption="Saved sources">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-connections-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=ba826e5f81a79bde7e9ff7ad93cb07c0" alt="Saved source connections in light mode" width="2880" height="1720" data-path="assets/images/filament-connections-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-connections-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=3528a07ce8753d2ca979275946e3d47e" alt="Saved source connections in dark mode" width="2880" height="1720" data-path="assets/images/filament-connections-dark.png" />
</Frame>

New source opens the connector catalog. It shows the connectors compiled into
the running server and labels each one alpha, beta, or stable.

<Frame caption="The connector catalog">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-connections-create-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=2235a4db6919c66e34ceea3263e1b40a" alt="Connector catalog in light mode" width="2880" height="1720" data-path="assets/images/filament-connections-create-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-connections-create-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=808c17698c25e103f00035808bc0b078" alt="Connector catalog in dark mode" width="2880" height="1720" data-path="assets/images/filament-connections-create-dark.png" />
</Frame>

Connecting one generates a form from that connector's config schema. The
connector declares its fields, types, defaults, and visibility rules, and the
form renders exactly those. Postgres CDC settings, for example, appear only
once you set replication to `cdc`.

Two details worth knowing:

* **Scope.** Connections hold connection-scoped fields only, the ones that
  describe reaching the system. Pipeline-scoped fields like a destination
  schema are set later, per pipeline.
* **Secrets.** Secret-typed fields are extracted on save and stored through
  the configured secrets provider. Reads return them masked, and editing
  leaves a stored secret in place unless you submit a new value.

Before saving, the server checks required fields, value types, and other local
configuration rules. It does not make a live connection at this point, so an
unreachable hostname or rejected password can still fail during discovery or
a run.

## Pipelines

The list view shows each pipeline with its schedule, recent run outcomes, and
last duration. Opening one gives you the canvas, the history, and the
settings.

<Frame caption="The pipelines list">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipelines-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=d39f906e3dfea2f4e9abe1b40a3a008d" alt="Pipelines list in light mode" width="2880" height="1720" data-path="assets/images/filament-pipelines-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipelines-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=6c42713a88d20a5e561cba4dbc9ade04" alt="Pipelines list in dark mode" width="2880" height="1720" data-path="assets/images/filament-pipelines-dark.png" />
</Frame>

### Canvas

The canvas edits the pipeline graph. Nodes are connections and edges route
selected resources between them. Standard sources let you choose full or
incremental reads and an appropriate destination write mode. CDC sources use
the connection's change stream and let the route append events or merge them
into current state. Incremental reads may also need a cursor column.
[Replication modes](/pages/guides/concepts/replication-modes) explains the
valid combinations.

Edits are validated as you work. Unmet requirements appear on the
edge itself, so a table without a primary key blocks an upsert route before
you save rather than failing at run time.

Saving creates a new immutable pipeline version. In-flight runs keep executing
against the version they started with.

<Frame caption="The pipeline canvas">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-canvas-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=15bb4f04db1e69778b716e5283b8a167" alt="Pipeline canvas in light mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-canvas-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-canvas-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=97dc8bbf1d3c1d29d7a1e1c8284564fd" alt="Pipeline canvas in dark mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-canvas-dark.png" />
</Frame>

### History

Every run, newest first, with per-resource record and byte tallies and a
final status. An active run streams, so progress arrives as the engine
publishes it rather than on a poll.

Statuses map directly to engine states. A failed run that saved resumable
progress enters `PARTIAL` and continues from its last checkpoint when
requested again. See
[Runs and recovery](/pages/guides/concepts/runs-and-recovery).

<Frame caption="Run history">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-history-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=cc1b809d3f4ab6dca4282bf17cb91fe5" alt="Pipeline run history in light mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-history-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-history-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=8e144c363523ba256194980b7dae2c72" alt="Pipeline run history in dark mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-history-dark.png" />
</Frame>

### Settings

Name and description, a cron schedule with a timezone and an overlap policy,
and the worker configuration that sizes the machines runs execute on.
Metadata edits apply in place and do not create a version.

<Frame caption="Pipeline settings">
  <img className="block dark:hidden" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-settings-light.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=77e078ff88924b9b48b78b8e6cca97ad" alt="Pipeline settings in light mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-settings-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/galaxy-filament/yaBavYKQJ_HPSIYt/assets/images/filament-pipeline-settings-dark.png?fit=max&auto=format&n=yaBavYKQJ_HPSIYt&q=85&s=ad941e5257e9d9a02896e05b08f08b6b" alt="Pipeline settings in dark mode" width="2880" height="1720" data-path="assets/images/filament-pipeline-settings-dark.png" />
</Frame>

## Contributing to the web app

For contributors, the web app lives in `ui/` as a React 18 and TypeScript app
built with Vite:

* **Routing and data.** TanStack Router with file-based routes in
  `src/routes/`, and TanStack Query for server state. API calls go through
  ConnectRPC's web transport with `connect-query` bindings.
* **Generated types.** `src/gen/` holds the protobuf-generated TypeScript.
  Never edit it by hand. `pnpm codegen` (or `just gen` at the repo root)
  regenerates it with `buf` after a proto change.
* **Design system.** Components, tokens, and theming come from
  [`@galaxy-io/dls`](https://www.npmjs.com/package/@galaxy-io/dls). The app
  mounts its stylesheet and `GalaxyThemeProvider` in `main.tsx`. Browse the
  catalog at [storybook.getgalaxy.io](https://storybook.getgalaxy.io) before
  building anything new.
* **Styling and the canvas.** Component-local styles use Linaria. The canvas
  is built on `@xyflow/react`. Icons are Phosphor, with project SVGs compiled
  by `pnpm assets`.
* **Formatting.** Biome formats and lints the UI.

The server serves the compiled bundle only when built with the `embedui` tag,
which `just binaries` and the published images do. For development, `just ui`
runs Vite on `:5173` against a local API. See
[Local development](/pages/guides/contributing/local-development) for the
rest of the workflow.
