# Workspace & Crate Map

> How the ~65-crate Rust workspace is organized: the role of the app binary versus the crates/* libraries, default-members, the local workspace dependency graph, and which crates own which responsibility.

- Repository: warpdotdev/warp
- GitHub: https://github.com/warpdotdev/warp
- Human wiki: https://grok-wiki.com/public/wiki/warpdotdev-warp-a55b6d0c09b5
- Complete Markdown: https://grok-wiki.com/public/wiki/warpdotdev-warp-a55b6d0c09b5/llms-full.txt

## Source Files

- `Cargo.toml`
- `app/Cargo.toml`
- `crates/warp_core/src/lib.rs`
- `crates/warp_terminal/src/lib.rs`
- `crates/warpui/src/lib.rs`
- `crates/warp_util/src/lib.rs`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [Cargo.toml](Cargo.toml)
- [app/Cargo.toml](app/Cargo.toml)
- [crates/warp_core/src/lib.rs](crates/warp_core/src/lib.rs)
- [crates/warp_terminal/src/lib.rs](crates/warp_terminal/src/lib.rs)
- [crates/warpui/src/lib.rs](crates/warpui/src/lib.rs)
- [crates/warpui_core/src/lib.rs](crates/warpui_core/src/lib.rs)
- [crates/warp_util/src/lib.rs](crates/warp_util/src/lib.rs)
- [crates/ai/src/lib.rs](crates/ai/src/lib.rs)
- [crates/command/src/lib.rs](crates/command/src/lib.rs)
- [crates/editor/src/lib.rs](crates/editor/src/lib.rs)
- [crates/warp_terminal/Cargo.toml](crates/warp_terminal/Cargo.toml)
- [crates/warp_core/Cargo.toml](crates/warp_core/Cargo.toml)
- [crates/warpui_core/Cargo.toml](crates/warpui_core/Cargo.toml)
</details>

# Workspace & Crate Map

Warp is built as a single Cargo workspace that contains one application package (`app/`) and roughly 65 library crates under `crates/*`. The workspace root declares its members with two glob/path entries — `crates/*` and `app` — and pins the v2 feature resolver, so every directory under `crates/` is automatically a workspace member without being individually listed. This page explains how that workspace is organized: how the binary package relates to the libraries, what `default-members` selects, how local crates are wired together through path dependencies, and which crate owns which responsibility.

The most important structural fact is that responsibility is split by *layer*, not by feature. A small set of utility and UI-framework crates sit at the bottom, domain crates such as `warp_core` and `warp_terminal` build on them, capability crates (`ai`, `lsp`, `mcp`, `graphql`, `persistence`) provide subsystems, and the `app` package at the top composes everything into shippable binaries. This page verifies that layering directly from the manifests and crate roots rather than from naming alone.

Sources: [Cargo.toml:1-6](), [Cargo.toml:30-95]()

## Workspace membership and the resolver

The workspace is defined at the repository root. Members are expanded from the `crates/*` glob plus the explicit `app` entry, and the modern dependency resolver is selected:

```toml
# Cargo.toml
[workspace]
members = [
  "crates/*",
  "app",
]
resolver = "2"
```

Because the glob captures every subdirectory of `crates/`, the workspace currently holds ~65 library crates plus the `app` package. Shared package metadata (author, AGPL-3.0 license, `publish = false`) is defined once in `[workspace.package]` and inherited by member crates via `*.workspace = true`.

Sources: [Cargo.toml:1-28](), [app/Cargo.toml:8-9]()

### Layered ownership model

The verified dependency edges below show that the workspace is not flat — crates form a directed acyclic layering from generic utilities up to the application binary.

```mermaid
flowchart TD
    subgraph App["Application package — app/"]
        APP["warp (lib) + bins:\nwarp-oss, warp, dev, stable, preview, integration"]
    end
    subgraph Domain["Domain & terminal crates"]
        CORE["warp_core\napp identity, channels, features,\npaths, telemetry, settings re-export"]
        TERM["warp_terminal\nmodel, shell, shared_session"]
        COMPL["warp_completer"]
    end
    subgraph Capability["Capability / subsystem crates"]
        AI["ai — agents, skills, index"]
        LSP["lsp"]
        MCP["mcp"]
        GQL["graphql (warp_graphql)"]
        PERS["persistence (diesel)"]
        SRV["warp_server_client"]
        EDIT["editor (warp_editor)"]
    end
    subgraph UIFW["UI framework"]
        WUI["warpui\nfonts, platform, rendering, windowing"]
        WUIC["warpui_core\nactions, elements, event, keymap"]
    end
    subgraph Foundation["Foundation utilities"]
        UTIL["warp_util"]
        SUM["sum_tree"]
        SET["settings / settings_value"]
        FEAT["warp_features"]
    end

    APP --> CORE & TERM & WUI & AI & LSP & MCP & GQL & PERS & SRV & EDIT
    TERM --> CORE & COMPL & UTIL
    CORE --> WUI & SET & FEAT & UTIL
    WUI --> WUIC
    WUIC --> SUM & UTIL
```

Sources: [crates/warp_terminal/Cargo.toml:33-35](), [crates/warp_core/Cargo.toml:1-95](), [crates/warpui/src/lib.rs:1-8](), [crates/warpui_core/Cargo.toml:72-79]()

## The `app` binary versus the `crates/*` libraries

The `app` package is both a library and a multi-binary target. Its `[lib]` is named `warp` (path `src/lib.rs`), and it declares `default-run = "warp-oss"`, with `autobins = false` so that binaries are only the ones explicitly listed. Each channel is a separate `[[bin]]` that points at a thin entry file under `src/bin/`, while remaining "exactly identical to our main binary" apart from icon, app name, and channel-specific flag overrides:

| Binary | Entry path | Purpose |
| --- | --- | --- |
| `warp-oss` | `src/bin/oss.rs` | Default run target; open-source build |
| `warp` | `src/bin/local.rs` | Local developer build |
| `dev` / `stable` / `preview` | `src/bin/{dev,stable,preview}.rs` | Release channels (`preview` requires the `preview_channel` feature) |
| `integration` | `src/bin/integration.rs` | Integration-test harness binary |
| `generate_settings_schema` | `src/bin/generate_settings_schema.rs` | Tooling to emit the settings JSON schema |

The `app` package is the composition root: it depends on essentially every domain and capability crate — `warp_core`, `warp_terminal`, `warpui`, `ai`, `lsp`, `mcp` (via `rmcp`), `warp_graphql`, `persistence`, `warp_server_client`, `editor` (as `warp_editor`), `vim`, `remote_server`, and many more — and owns the enormous `[features]` table (hundreds of feature flags, the `default` set, plus platform-conditional dependency blocks for macOS, wasm, Windows, and Unix). The `crates/*` libraries, by contrast, each own one coherent concern and avoid binary/composition concerns.

Sources: [app/Cargo.toml:1-54](), [app/Cargo.toml:218-260](), [app/Cargo.toml:432-469]()

## `default-members` — what builds and tests by default

While `members` includes every crate, `default-members` narrows what `cargo build`/`cargo test` operate on when no `-p` is given:

```toml
# Cargo.toml
default-members = [
  "app",
  "crates/channel_versions",
  "crates/command",
  "crates/editor",
  "crates/graphql",
  "crates/markdown_parser",
  "crates/sum_tree",
  "crates/warpui",
  "crates/warp_completer",
  "crates/warp_terminal",
  "crates/warp_util",
]
```

The accompanying comment states the intent of the exclusions: `serve-wasm` is omitted because it is "a helper for serving wasm binaries and not something we want to regularly compile or run tests against," and `integration` is omitted because it "is only used for testing." In practice the listed set is `app` plus a curated group of library crates whose own test suites run by default; because `app` transitively depends on nearly all other crates, building the default members still compiles the broader graph.

Sources: [Cargo.toml:8-23]()

## The local dependency graph

Local crates are wired together through `[workspace.dependencies]`, where each internal crate is registered with a `path = "crates/..."` entry. Downstream crates then refer to them with `crate.workspace = true` instead of repeating paths or versions — the file's own comment notes this "lets us reference them in other crates without specifying a path."

A notable subtlety is that the **dependency key name does not always match the directory name**. The workspace deliberately re-labels several crates:

| Dependency name | Filesystem path |
| --- | --- |
| `warp_editor` | `crates/editor` |
| `warp_graphql` | `crates/graphql` |
| `warp_isolation_platform` | `crates/isolation_platform` |
| `warp_managed_secrets` | `crates/managed_secrets` |
| `virtual-fs` | `crates/virtual_fs` |
| `warp` | `app` |

A few crates also opt out of default features at the workspace level (`channel_versions`, `settings_value`, `warpui_extras`).

The actual edges confirm the layering. `warp_terminal` depends only on `warp_completer`, `warp_core`, and `warp_util`. `warp_core` depends on lower-level crates including `settings`, `warp_features`, `warp_util`, `websocket`, plus the UI crates `warpui` and `warpui_extras`. `warpui` re-exports `warpui_core`, which in turn depends on `sum_tree` and `warp_util`. `warp_util` itself pulls in no internal crates — it is the foundation.

Sources: [Cargo.toml:30-95](), [crates/warp_terminal/Cargo.toml:33-35](), [crates/warp_core/Cargo.toml:1-95](), [crates/warpui/src/lib.rs:6-7](), [crates/warpui_core/Cargo.toml:72-79]()

## Which crate owns which responsibility

The crate roots make ownership explicit through their public module trees. The table summarizes the central crates verified from their `lib.rs`:

| Crate | Role (from `lib.rs` modules / doc) |
| --- | --- |
| `warp_util` | "Generic utilities and helpers available for use across all internal warp crates" — `file`, `path`, `git`, `host_id`, `sync`, `remote_path` |
| `warpui_core` | UI framework core — `actions`, `elements`, `event`, `keymap`, `accessibility`, `clipboard`, `image_cache`, `fonts` |
| `warpui` | UI rendering/windowing layer; adds `fonts`, `platform`, `rendering`, `windowing` and re-exports all of `warpui_core` |
| `warp_core` | App-domain foundation — `app_id`, `channel`, `features`, `paths`, `telemetry`, `session_id`, `user_preferences`; re-exports `settings` and its macros |
| `warp_terminal` | Terminal domain — `model`, `shell`, `shared_session` |
| `command` | Cross-platform process spawning; drop-in replacements for `std::process::Command` / `async_process::Command` (Windows `no_window` handling) |
| `ai` | Agent/LLM subsystem — `agent`, `api_keys`, `skills`, `index`, `project_context`, `LLMId` |
| `editor` (`warp_editor`) | Text editing — `content`, `editor`, `selection`, `search`, `multiline`, `render` |
| `settings` | Settings system — `macros`, `manager` (`SettingsManager`), `schema` |
| `graphql` (`warp_graphql`) | GraphQL `api`, `client`, `scalars`, `managed_secrets` |
| `persistence` | Local storage via Diesel; `model`, `schema`, embedded `MIGRATIONS` (gated on `local_fs`) |
| `warp_server_client` | Cloud client — `auth` (`UserUid`), `cloud_object`, `drive`, `ids` |
| `lsp` | Language-server integration — `CommandBuilder`, `manager`, `servers`, `supported_servers` |
| `mcp` | Model Context Protocol transport (`sse_transport`) |

`warp_core`'s root also re-exports `settings` and its declarative macros (`define_setting`, `define_settings_group`, …) "for backward compatibility," which is why many crates reach the settings system through `warp_core` rather than depending on `settings` directly.

Sources: [crates/warp_util/src/lib.rs:1-23](), [crates/warpui_core/src/lib.rs:1-18](), [crates/warpui/src/lib.rs:1-8](), [crates/warp_core/src/lib.rs:1-31](), [crates/warp_terminal/src/lib.rs:1-3](), [crates/command/src/lib.rs:1-18](), [crates/ai/src/lib.rs:1-16](), [crates/editor/src/lib.rs:1-9](), [crates/settings/src/lib.rs:1-18](), [crates/graphql/src/lib.rs:1-7](), [crates/persistence/src/lib.rs:1-6](), [crates/warp_server_client/src/lib.rs:1-7](), [crates/lsp/src/lib.rs:1-18](), [crates/mcp/src/lib.rs:1]()

## Per-crate build tuning

The workspace recognizes that some crates are hot paths even in debug builds and overrides their optimization level via `[profile.dev.package]`. For example, `warp_terminal.opt-level = 3` is applied because the comment explains it is needed to "improve the performance of core terminal logic," while keeping the rest of the dev build fast. Similar per-crate overrides exist for font/text layout, image processing, and profiling crates. This is a workspace-level mechanism rather than something each crate configures itself, reinforcing that build policy is centralized in the root manifest.

Sources: [Cargo.toml:406-436]()

## Summary

The Warp workspace is a layered Cargo monorepo: one root manifest expands `crates/*` and `app` into ~65 members under resolver v2, registers every internal crate as a path dependency so others can reference it with `crate.workspace = true`, and centralizes license, feature, profile, and per-crate optimization policy. The `app` package is the composition root — a library plus several channel binaries that depend on nearly the entire crate graph — while `default-members` selects `app` and a curated set of library crates for default builds/tests, intentionally excluding `serve-wasm` and `integration`. Responsibilities flow bottom-up from `warp_util` and `warpui_core` through `warp_core`/`warp_terminal` and capability crates like `ai`, `lsp`, and `persistence`, with the dependency-key-to-directory remapping (`warp_editor → editor`, `warp_graphql → graphql`, and others) being the main naming subtlety to watch when navigating the tree. This organization is provider-neutral: the crate boundaries and path-based dependency wiring shown here are independent of any model provider or hosted service, so the same map applies regardless of how AI capability crates such as `ai` are configured.

Sources: [Cargo.toml:1-95](), [app/Cargo.toml:1-54]()
