# App definition

URL: /code/file-conventions/products/app · Id: `page:code/file-conventions/products/app`

> The typed keys of an App's definition file, each linked to the page that explains it, with Leaseline's App as the example.

An [App](/business/nouns/app) is declared in one file in its [folder](/code/file-conventions/apps), `apps/[app]/app.mdx`, and a [Product](/business/nouns/product) sells it by naming `App` in its `$type`. A wrong key or value fails its check before it compiles.

## Keys
`apps/[app]/app.mdx` declares one App. Frontmatter only.

| Key | Type | Required | Holds |
| --- | --- | --- | --- |
| [`kind`](/products/app/anatomy#app-kinds) | `saas` \| `admin` \| `directory` \| `commerce` | No | The App kind; `saas` when unset |
| [`mount`](/code/routing) | path | No | Where it serves on the Domain; `/app`, or `/admin` for `admin` |
| [`nouns`](/products/app/app-shell) | Noun names | Yes | The Nouns it shows, a list and a record screen each |
| [`personas`](/products/app/tenancy-and-identity#personas) | map | No | Each Persona who signs in |
| [`personas.*.may`](/code/platform/permissions) | Verb ids | No | The Verbs that Persona may call; each one is a button and a form |
| [`slots`](/products/app/customize#slots) | map | No | A Component per slot: `list.toolbar`, `list.empty`, `record.header`, `record.aside`, `record.actions`, `record.tab`, `form.after`, `dashboard.section` |

```mdx title="apps/portal/app.mdx"
---
kind: saas
mount: /app
nouns: [Lease]
personas:
  manager: { may: [Lease.create, Lease.renew, Lease.notify] }
  resident: { may: [Lease.get] }
slots:
  record.aside: Timeline
---
```

## What it builds
[SoftwareBuilder](/code/builders/software) compiles the file into the parts the [App](/business/nouns/app)'s [anatomy](/products/app/anatomy) lists: screens, the API and packages, each [Tenant](/business/nouns/tenant), sign-in, plans and the admin App. [`App.publish`](/business/nouns/app/publish) serves the result.

## Good to know
- `kind` takes `saas`, `admin`, `directory` or `commerce`; [App kinds](/products/app/anatomy#app-kinds) says what each adds.
- Every App gets an `admin` App beside it; declare one only to change it.
- A [view override](/code/file-conventions/views) replaces one screen, and a slot replaces one part of a screen.