> For AI agents: the complete Sanity documentation index is available at [https://www.sanity.io/docs/llms.txt](https://www.sanity.io/docs/llms.txt).

# Migrate an SDK app to Dashboard 2.0

Move an existing SDK app to utilise Dashboard 2.0: upgrade to App SDK v3, switch to defineApplication, and deploy it as a new application.

## Where your app renders now

Your App SDK app rendered into a single full-page surface. In Dashboard 2.0 that surface is called the window view, and it is still the default. If you set `entry` in `defineApplication`, the CLI creates the window view for you and your app renders exactly where it used to.

What changes is that `defineApplication` is now a container rather than a single app surface. One application has one job, but it can render parts of that job on several surfaces: a window view, one or more panel views in the column beside the dock, a tile view on the home page, and web workers running in the background. You opt into the extra surfaces only when you need them.

## Prerequisites

- An SDK app with a `sanity.cli.ts` file.
- React 19.2 or later.
- Your organization ID. Your existing `sanity.cli.ts` already has it as `app.organizationId`.

## Upgrade to SDK v3

Dashboard 2.0 signs your app in and passes it the current organization over its message bus. SDK 3.9.0 and later support this. If you're upgrading from v2, follow [App SDK v2 to v3](https://www.sanity.io/docs/help/sdk-v2-to-v3) for the breaking changes.

**npm**

```sh
npm install @sanity/sdk@latest @sanity/sdk-react@latest react@latest react-dom@latest
npm install --save-dev sanity@latest
```

**pnpm**

```sh
pnpm add @sanity/sdk@latest @sanity/sdk-react@latest react@latest react-dom@latest
pnpm add --save-dev sanity@latest
```

## Switch the configuration to defineApplication

Wrap `app` in `defineApplication`, add `slug`, `name`, and `title`, and remove `deployment.appId`:

- `organizationId`: Keep your existing value.
- `entry`: Set it explicitly, `defineApplication` doesn't default to `./src/App.tsx.`
- `slug`: The app's slug in Dashboard and the hostname it deploys to. Slugs are currently unique across all organizations, so choose one specific to your app.
- `name`: The app's stable identity. You can't change it after the first deploy. Defaults to `slug`.
- `title`: The label on the Dashboard dock button.

You don't need to change `src/App.tsx`. Keep its default export and the `SanityApp` `config`, which still sets the project and dataset your app reads from. You can see a before & after example below:

**sanity.cli.ts (before)**

```typescript
import {defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  app: {
    organizationId: 'your-organization-id',
    entry: './src/App.tsx',
  },
  deployment: {
    appId: 'your-app-id',
  },
})
```

**sanity.cli.ts (after)**

```typescript
import {defineApplication, defineCliConfig} from 'sanity/cli'

export default defineCliConfig({
  app: defineApplication({
    organizationId: 'your-organization-id',
    slug: 'content-app',
    name: 'content-app',
    title: 'Content app',
    entry: './src/App.tsx',
  }),
})
```

## Run the app in the Dashboard

The CLI starts a local Dashboard on the configured port (3333 by default). Open the Dashboard URL the CLI prints. You no longer need `--load-in-dashboard`; the CLI ignores it for these apps. If you run multiple apps locally they’ll all connect to the same local Dashboard

**npm**

```shell
npx sanity dev
```

**pnpm**

```shell
pnpm dlx sanity dev
```

**yarn**

```shell
yarn dlx sanity dev
```

**bun**

```shell
bunx sanity dev
```

## Deploy the new application

The first deploy creates a new application and prints its URL. The CLI then prints a `deployment.appId`. Add it to `sanity.cli.ts` so later deploys update this application instead of creating another.

If you want to keep this new app hidden from users whilst you migrate and test then set `visibility: 'unlisted'` in the `defineApplication` function. See [Application Visibility](https://www.sanity.io/docs/app-sdk/sdk-configuration) for more information.

> [!WARNING]
> Deploying creates a new application
> You can't convert an application you've already deployed. Deploying with `defineApplication` creates a new application at a new URL, and the existing application stays in your organization until you undeploy it.
> Apps you don't migrate keep working in Dashboard 2.0 however they will not receive new features.

**npm**

```shell
npx sanity deploy
```

**pnpm**

```shell
pnpm dlx sanity deploy
```

**yarn**

```shell
yarn dlx sanity deploy
```

**bun**

```shell
bunx sanity deploy
```

## Undeploy the existing app (optional)

Until you remove it, the existing app appears in the Dashboard next to the new one. To remove it with the CLI, run `sanity undeploy` from a copy of the project that still has the old configuration, with `deployment.appId`. Once `sanity.cli.ts` uses `defineApplication`, `sanity undeploy` targets the new application instead:

**npm**

```shell
npx sanity undeploy
```

**pnpm**

```shell
pnpm dlx sanity undeploy
```

**yarn**

```shell
yarn dlx sanity undeploy
```

**bun**

```shell
bunx sanity undeploy
```

## Next steps

[Extend the Dashboard](https://www.sanity.io/docs/dashboard-beta/extension-api)
Add panels, tiles, and background services to your app.

[Extension API reference](https://www.sanity.io/docs/dashboard-beta/extension-api-reference)
Look up every defineApplication field.

