# Configuration

`app.manifest.json` describes the entire app in a single JSON file. It's the source of truth: surfaces, theme, locale, backend, and plugins. This page is the map of every top-level block — what it does and what `fayz doctor` validates.

## The shape of the manifest

A freshly created admin app looks like this (`manifestVersion` is always `2` in this generation):

```json
{
  "manifestVersion": 2,
  "id": "my-store",
  "name": "My Store",
  "backend": { "provider": "mock" },
  "locale": { "default": "pt-BR", "supported": ["pt-BR", "en"], "currency": "BRL" },
  "theme": { "brand": "violet" },
  "surfaces": {
    "admin": {
      "scaffold": "admin",
      "plugins": [{ "id": "dashboard" }],
      "pages": []
    }
  }
}
```

The four required fields are `manifestVersion`, `id`, `name`, and `surfaces`. Everything else is optional and has a sensible default.

## The top-level blocks

| Field | Role |
| --- | --- |
| `id` | Identifier in kebab-case (`^[a-z0-9][a-z0-9-]*$`). |
| `name` | The app's display name. |
| `backend` | Where the data comes from. A `{ provider, ... }` object — detailed below. |
| `locale` | Language, supported languages, and currency. |
| `theme` | The brand: `brand`, `radius`, `mode` (see [Theming](/en/docs/apps/theming)). |
| `permissions` | Declaration of features and actions (deny-by-default in multi-tenant). |
| `surfaces` | The faces of the app. At least one is required. |

## The `backend` block

`provider` decides where the data comes from. The accepted values:

| `provider` | What for |
| --- | --- |
| `mock` | In-memory sample data, zero configuration. This is the scaffold default. When you consume the packages in code, mock providers start out empty — see [Mock and sample data](/en/docs/apps/mock-and-sample-data) to seed them. |
| `supabase` | A real Supabase project. Comes with `projectRef`. |
| `fayz-api` | The managed Fayz API. |
| `fayz-shop` | The Fayz e-commerce backend. |
| `custom` | Your own adapter, referenced by `adapterId`. |

Switching from `mock` to `supabase` is the middle step of the tutorial — see [Supabase](/en/docs/data/supabase):

```json
{ "backend": { "provider": "supabase", "projectRef": "your-project-ref" } }
```

## Surfaces and plugins

Inside `surfaces`, each surface declares a `scaffold` (required), a list of `plugins`, and a list of `pages`. Wiring up a capability means adding `{ "id": "..." }` to the `plugins` list — the packages already ship in the generated app's dependencies, so there's nothing to install and nothing to edit in `src/plugins.generated.ts`. Each `pluginRef` accepts `config` (plugin options) and `enabled` (to switch it off without removing it).

Since routes and the menu are derived from that list, the details live in [Routing and navigation](/en/docs/apps/routing-and-navigation).

## Two ways to configure

The scaffold gives you the **manifest-first** shape: you edit JSON and the platform renders it. There's also the **code-first** shape, where configuration lives in `src/` (via `defineSaas` / `defineStorefront`). `fayz doctor` recognizes both: an app without an `app.manifest.json` but with a `package.json` is treated as a code-first app — doctor runs the boundary checks and passes. Start with the manifest shape; it covers most cases and it's the one the platform edits live.

## Always validate

After any edit, run doctor. It checks the manifest structure, the referenced plugins, and the architecture boundaries:

```bash
npx @fayz-ai/cli doctor
```

An off-pattern `id` or a surface without a `scaffold` makes doctor exit with an error — on purpose, so you catch the problem before shipping. Today doctor validates the **structure** of the manifest and the architecture boundaries; validation of enum *values* (like `backend.provider` or `theme.brand`) is on the way — an SDK fix is in PR.

---

Next: apply your brand in [Theming](/en/docs/apps/theming).
