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

# Templates and the manifest

> How a template declares its services, modes, database, and seeds — and the six that ship today.

A **template** is a directory that knows how to be cloned. It contains the app's
code (backend, optional frontend, MCP server) plus a `clone.manifest.json` that
tells the CLI everything it needs to spin, migrate, health-check, and seed it.

Templates live under the templates directory (the monorepo `apps/` by default;
override with `ASYM_TEMPLATES_DIR`). The published CLI bundles each manifest with
its compose file, so it resolves templates from its own bundle with no monorepo
present. The CLI discovers a template by reading each manifest's `name` — so
`apps/slack-clone/` declares the name `slack`, which is what you type in
`asymmetric spin slack`.

## The manifest

Here's the Slack template's `clone.manifest.json`, annotated:

```json theme={null}
{
  "name": "slack",                         // canonical id used on the CLI
  "displayName": "Slack",
  "realProduct": "slack",                  // what `verify` scores fidelity against
  "services": {
    "backend": {
      "image": "ghcr.io/asymmetric-ai/asymmetric-slack-backend:latest", // pulled, not built
      "port": 3001,                        // container port
      "health": "/api/health"              // polled until healthy on spin
    },
    "frontend": {
      "build": "./frontend",               // the one service still built from source
      "port": 5173,
      "optional": true
    }
  },
  "modes": {                               // named service sets
    "api": ["backend"],
    "full": ["backend", "frontend"]
  },
  "database": {
    "migrations": "./supabase/migrations", // .sql files, run in sorted order
    "nameTemplate": "clone_{id}"           // per-clone database name
  },
  "redis": {
    "prefixTemplate": "{id}:"              // per-clone key prefix
  },
  "seed": {
    "fixtures": "./seeds/*.sql",           // deterministic fixture packs
    "ai": {
      "entities": ["users", "channels", "messages"]
    }
  }
}
```

Backends declare an `image` (pulled and digest-pinned at spin). A service can
instead declare `build` for a local build context — today only Slack's optional
frontend does.

## Fields that matter

| Field                   | Drives                                                                   |
| ----------------------- | ------------------------------------------------------------------------ |
| `name`                  | The identifier you type (`spin <name>`, `verify <name>`).                |
| `services[].image`      | The published image the CLI pulls and runs (digest-pinned).              |
| `services[].health`     | The endpoint `spin` and `reset` poll before declaring the clone healthy. |
| `modes`                 | What `--mode` accepts; the first key is the default.                     |
| `database.migrations`   | The `.sql` files run on create and replayed on `reset`.                  |
| `database.nameTemplate` | How the per-clone database is named (`{id}` is substituted).             |
| `redis.prefixTemplate`  | The per-clone Redis key namespace.                                       |
| `seed.fixtures`         | The glob of named fixture packs `seed --fixture` can load.               |
| `seed.ai.entities`      | What AI seeding generates for this template.                             |

## Ready-made templates

Six templates ship today. Each backend is a published image; `verify` scores it
against the real product's live API documentation.

<CardGroup cols={2}>
  <Card title="Slack" icon="slack" href="/templates/slack">
    RPC Web API, MCP server, and a frontend. The `{ok}` envelope, Slack-format
    ids, byte-identical events. Modes: `api`, `full`.
  </Card>

  <Card title="Stripe" icon="stripe" href="/templates/stripe">
    REST API: customers, payments, invoices, subscriptions, refunds, and signed
    webhooks. API-only.
  </Card>

  <Card title="Notion" icon="file-lines" href="/templates/notion">
    REST API: databases, data sources, pages, blocks, views, comments, file
    uploads, search — with Notion's rate limits. API-only.
  </Card>

  <Card title="HubSpot" icon="bullhorn" href="/templates/hubspot">
    CRM REST API: generic objects, v4 associations, properties, pipelines,
    owners, OAuth tokens, and HubSpot-accurate rate limiting. API-only.
  </Card>

  <Card title="GitHub" icon="github" href="/templates/github">
    REST API: repos, issues, pull requests, comments, labels, tokens, and rate
    limiting. API-only.
  </Card>

  <Card title="Linear" icon="diagram-project" href="/templates/linear">
    GraphQL API: issues, projects, teams, cycles, and webhooks. API-only.
  </Card>
</CardGroup>

Default container ports are `slack 3001`, `linear 3002`, `stripe 3003`,
`notion 3004`, `hubspot 3005`, `github 3006`; the host port for each clone is
allocated at spin time from your range (default `3000–3999`).

Templates are built and maintained by asymmetric — you spin and use them, you
don't author your own.
