---
title: Getting Started
icon: "rocket"
description: Create your first Twenty app in minutes.
---

## What are apps?

Apps let you extend Twenty with custom objects, fields, logic functions, front components, AI skills, and more — all managed as code. Instead of configuring everything through the UI, you define your data model and logic in TypeScript and deploy it to one or more workspaces.

## Prerequisites

Before you begin, make sure the following is installed on your machine:

- **Node.js 24+** — [Download here](https://nodejs.org/)
- **Yarn 4** — Comes with Node.js via Corepack. Enable it by running `corepack enable`
- **Docker** — [Download here](https://www.docker.com/products/docker-desktop/). Required to run a local Twenty instance. Not needed if you already have a Twenty server running.

## Create your first app

### Scaffold your app

Open a terminal and run:

```bash filename="Terminal"
npx create-twenty-app@latest my-twenty-app
```

You will be prompted to enter a name and a description for your app. Press **Enter** to accept the defaults.

This creates a new folder called `my-twenty-app` with everything you need.

### Set up a local Twenty instance

The scaffolder will ask:

> **Would you like to set up a local Twenty instance?**

- **Type `yes`** (recommended) — This pulls the `twenty-app-dev` Docker image and starts a local Twenty server on port `2020`. Make sure Docker is running before you continue.
- **Type `no`** — Choose this if you already have a Twenty server running locally.

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
</div>

### Sign in to your workspace

Next, a browser window will open with the Twenty login page. Sign in with the pre-seeded demo account:

- **Email:** `tim@apple.dev`
- **Password:** `tim@apple.dev`

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
</div>

### Authorize the app

After you sign in, you will see an authorization screen. This lets your app interact with your workspace.

Click **Authorize** to continue.

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
</div>

Once authorized, your terminal will confirm that everything is set up.

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
</div>

### Start developing

Go into your new app folder and start the development server:

```bash filename="Terminal"
cd my-twenty-app
yarn twenty dev
```

This watches your source files, rebuilds on every change, and syncs your app to the local Twenty server automatically. You should see a live status panel in your terminal.

For more detailed output (build logs, sync requests, error traces), use the `--verbose` flag:

```bash filename="Terminal"
yarn twenty dev --verbose
```

<Warning>
Dev mode is only available on Twenty instances running in development (`NODE_ENV=development`). Production instances reject dev sync requests. Use `yarn twenty deploy` to deploy to production servers — see [Publishing Apps](/developers/extend/apps/publishing) for details.
</Warning>

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/dev.jpg" alt="Dev mode terminal output" />
</div>

#### One-shot sync with `yarn twenty dev --once`

If you do not want a watcher running in the background (for example in a CI pipeline, a git hook, or a scripted workflow), pass the `--once` flag. It runs the same pipeline as `yarn twenty dev` — build manifest, bundle files, upload, sync, regenerate the typed API client — but **exits as soon as the sync completes**:

```bash filename="Terminal"
yarn twenty dev --once
```

| Command | Behavior | When to use |
|---------|----------|-------------|
| `yarn twenty dev` | Watches your source files and re-syncs on every change. Keeps running until you stop it. | Interactive local development — you want the live status panel and instant feedback loop. |
| `yarn twenty dev --once` | Performs a single build + sync, then exits with code `0` on success or `1` on failure. | Scripts, CI, pre-commit hooks, AI agents, and any non-interactive workflow. |

Both modes require a Twenty server running in development mode and an authenticated remote — the same prerequisites apply.

### See your app in Twenty

Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) in your browser. Navigate to **Settings > Apps** and select the **Developer** tab. You should see your app listed under **Your Apps**:

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
</div>

Click on **My twenty app** to open its **application registration**. A registration is a server-level record that describes your app — its name, unique identifier, OAuth credentials, and source (local, npm, or tarball). It lives on the server, not inside any specific workspace. When you install an app into a workspace, Twenty creates a workspace-scoped **application** that points back to this registration. One registration can be installed across multiple workspaces on the same server.

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
</div>

Click **View installed app** to see the installed app. The **About** tab shows the current version and management options:

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app — About tab" />
</div>

Switch to the **Content** tab to see everything your app provides — objects, fields, logic functions, and agents:

<div style={{textAlign: 'center'}}>
  <img src="/images/docs/developers/extends/apps/app-in-ui-4.png" alt="Installed app — Content tab" />
</div>

You are all set! Edit any file in `src/` and the changes will be picked up automatically.

---

## What you can build

Apps are composed of **entities** — each defined as a TypeScript file with a single `export default`:

| Entity | What it does |
|--------|-------------|
| **Objects & Fields** | Define custom data models (like Post Card, Invoice) with typed fields |
| **Logic functions** | Server-side TypeScript functions triggered by HTTP routes, cron schedules, or database events |
| **Front components** | React components that render inside Twenty's UI (side panel, widgets, command menu) |
| **Skills & Agents** | AI capabilities — reusable instructions and autonomous assistants |
| **Views & Navigation** | Pre-configured list views and sidebar menu items for your objects |
| **Page layouts** | Custom record detail pages with tabs and widgets |

Head over to [Building Apps](/developers/extend/apps/building) for a detailed guide on each entity type.

---

## Project structure

The scaffolder generates the following file structure:

```text filename="my-twenty-app/"
my-twenty-app/
  package.json
  yarn.lock
  .gitignore
  .nvmrc
  .yarnrc.yml
  .oxlintrc.json
  tsconfig.json
  tsconfig.spec.json                          # TypeScript config for tests
  vitest.config.ts                            # Vitest test runner configuration
  LLMS.md
  README.md
  .github/
    └── workflows/
        └── ci.yml                            # GitHub Actions CI workflow
  public/                                     # Public assets (images, fonts, etc.)
  src/
  ├── application-config.ts                   # Required — main application configuration
  ├── default-role.ts                         # Default role for logic functions
  ├── constants/
  │   └── universal-identifiers.ts            # Auto-generated UUIDs and app metadata
  └── __tests__/
      ├── setup-test.ts                       # Test setup (server health check, config)
      └── app-install.integration-test.ts     # Integration test
```

### Starting from an example

To start from a more complete example with custom objects, fields, logic functions, front components, and more, use the `--example` flag:

```bash filename="Terminal"
npx create-twenty-app@latest my-twenty-app --example postcard
```

Examples are sourced from the [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) directory on GitHub. You can also scaffold individual entities into an existing project with `yarn twenty add` (see [Building Apps](/developers/extend/apps/building#scaffolding-entities-with-yarn-twenty-add)).

### Key files

| File / Folder | Purpose |
|---|---|
| `package.json` | Declares your app name, version, and dependencies. Includes a `twenty` script so you can run `yarn twenty help` to see all commands. |
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
| `src/default-role.ts` | Default role that controls what your logic functions can access. |
| `src/constants/universal-identifiers.ts` | Auto-generated UUIDs and app metadata (display name, description). |
| `src/__tests__/` | Integration tests (setup + example test). |
| `public/` | Static assets (images, fonts) served with your app. |

## Local development server

The scaffolder already started a local Twenty server for you. To manage it later, use `yarn twenty server`:

| Command | Description |
|---------|-------------|
| `yarn twenty server start` | Start the local server (pulls image if needed) |
| `yarn twenty server start --port 3030` | Start on a custom port |
| `yarn twenty server start --test` | Start a separate test instance on port 2021 |
| `yarn twenty server stop` | Stop the server (preserves data) |
| `yarn twenty server status` | Show server status, URL, version, and credentials |
| `yarn twenty server logs` | Stream server logs |
| `yarn twenty server logs --lines 100` | Show the last 100 log lines |
| `yarn twenty server reset` | Delete all data and start fresh |
| `yarn twenty server upgrade` | Pull the latest `twenty-app-dev` image and recreate the container |
| `yarn twenty server upgrade 2.2.0` | Upgrade to a specific version |

Data is persisted across restarts in two Docker volumes (`twenty-app-dev-data` for PostgreSQL, `twenty-app-dev-storage` for files). Use `reset` to wipe everything and start fresh.

### Upgrading the server image

Use `yarn twenty server upgrade` to check for a newer `twenty-app-dev` Docker image and update the container. The command pulls the image, compares it against the one the container was created from, and only recreates the container if the image actually changed. Your data volumes are preserved — only the container is replaced.

```bash filename="Terminal"
# Upgrade to the latest version (skips recreation if already up to date)
yarn twenty server upgrade

# Upgrade to a specific version
yarn twenty server upgrade 2.2.0
```

If a newer image is available and the container was running, the upgrade command automatically starts a new container with the updated image. Run `yarn twenty server start` afterward to wait for it to become healthy. If the image hasn't changed, the container is left untouched.

You can verify the running version with `yarn twenty server status`, which displays the `APP_VERSION` from the container.

### Running a test instance

Pass `--test` to any `server` command to manage a second, fully isolated instance — useful for running integration tests or experimenting without touching your main dev data.

| Command | Description |
|---------|-------------|
| `yarn twenty server start --test` | Start the test instance (defaults to port 2021) |
| `yarn twenty server stop --test` | Stop the test instance |
| `yarn twenty server status --test` | Show test instance status, URL, version, and credentials |
| `yarn twenty server logs --test` | Stream test instance logs |
| `yarn twenty server reset --test` | Wipe test data and start fresh |
| `yarn twenty server upgrade --test` | Upgrade the test instance image |

The test instance runs in its own Docker container (`twenty-app-dev-test`) with dedicated volumes (`twenty-app-dev-test-data`, `twenty-app-dev-test-storage`) and config, so it can run in parallel with your main instance without conflicts. Combine `--test` with `--port` to override the default 2021.

<Note>
  The server requires **Docker** to be running. If you see a "Docker not running" error, make sure Docker Desktop (or the Docker daemon) is started.
</Note>

## Manual setup (without the scaffolder)

If you prefer to set things up yourself instead of using `create-twenty-app`, you can do it in two steps.

**1. Add `twenty-sdk` and `twenty-client-sdk` as dependencies:**

```bash filename="Terminal"
yarn add twenty-sdk twenty-client-sdk
```

**2. Add a `twenty` script to your `package.json`:**

```json filename="package.json"
{
  "scripts": {
    "twenty": "twenty"
  }
}
```

You can now run `yarn twenty dev`, `yarn twenty help`, and all other commands.

<Note>
Do not install `twenty-sdk` globally. Always use it as a local project dependency so that each project can pin its own version.
</Note>

## Troubleshooting

If you run into issues:

- Make sure **Docker is running** before starting the scaffolder with a local instance.
- Make sure you are using **Node.js 24+** (`node -v` to check).
- Make sure **Corepack is enabled** (`corepack enable`) so Yarn 4 is available.
- Try deleting `node_modules` and running `yarn install` again if dependencies seem broken.

Still stuck? Ask for help on the [Twenty Discord](https://discord.com/channels/1130383047699738754/1130386664812982322).
