---
title: Next.js
description: Get started with Flexkit Studio in a new Next.js project
---

import { Callout } from 'nextra/components';
import { FileTree } from 'nextra/components';
import { Steps } from 'nextra/components';

# Next.js Quickstart

Create a new Flexkit Studio in a Next.js application and run it locally.



## Before you start

Use Node.js 22 or later and a package manager. [Create a Flexkit project](/docs/getting-started/create-project), copy its Project ID, and ensure your account can deploy its schema. These examples use a project you can safely populate with synthetic data.

Keep the generated application's package versions locked. See [compatibility](/docs/reference/compatibility) when upgrading. Use the directory layout shown here; adjust relative imports if you choose a `src` directory in Next.js.

<Steps>
### Create a new Next.js project

**pnpm**

```sh
pnpm create next-app@latest my-flexkit-app --yes
cd my-flexkit-app
```

**npm**

```sh
npx create-next-app@latest my-flexkit-app --yes
cd my-flexkit-app
```

**yarn**

```sh
yarn create next-app@latest my-flexkit-app --yes
cd my-flexkit-app
```

**bun**

```sh
bun create next-app@latest my-flexkit-app --yes
cd my-flexkit-app
```

### Install Flexkit Studio packages

**pnpm**

```sh
pnpm add @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer @flexkit/ai
```

**npm**

```sh
npm install @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer @flexkit/ai
```

**yarn**

```sh
yarn add @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer @flexkit/ai
```

**bun**

```sh
bun add @flexkit/studio @flexkit/desk @flexkit/asset-manager @flexkit/explorer @flexkit/ai
```

### Create the Flexkit configuration

Create a `flexkit.config.ts` file in the root of your project. This file defines the project schema used by the CLI. The separate Studio configuration below registers browser extensions.

```ts filename="flexkit.config.ts"
import { defineConfig, defineEntity } from '@flexkit/studio';

const categories = defineEntity({
  name: 'category',
  plural: 'categories',
  display: 'name',
  menu: { label: 'Categories' },
  attributes: [
    { name: 'name', label: 'Name', scope: 'local', dataType: 'string', inputType: 'text', searchable: true },
    { name: 'slug', label: 'Slug', scope: 'global', dataType: 'string', inputType: 'text', unique: true },
  ],
});

const products = defineEntity({
  name: 'product',
  plural: 'products',
  display: 'name',
  menu: { label: 'Products' },
  attributes: [
    { name: 'name', label: 'Name', scope: 'local', dataType: 'string', inputType: 'text', searchable: true },
    {
      name: 'sku',
      label: 'SKU',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      unique: true,
      searchable: true,
    },
    { name: 'price', label: 'Price', scope: 'local', dataType: 'float', inputType: 'number' },
    { name: 'image', label: 'Image', scope: 'global', dataType: 'asset', inputType: 'asset' },
    { name: 'status', label: 'Status', scope: 'global', dataType: 'string', inputType: 'text', defaultValue: 'draft' },
    {
      name: 'category',
      label: 'Category',
      scope: 'relationship',
      dataType: 'string',
      inputType: 'relationship',
      relationship: { mode: 'single', field: 'name', entity: 'category' },
    },
  ],
});

export default defineConfig({
  title: 'Catalog Studio',
  projectId: 'your-project-id',
  basePath: '/studio',
  scopes: [{ name: 'default', label: 'Default', isDefault: true }],
  schema: [products, categories],
});
```

Keep this configuration free of browser extension imports so the CLI can load it. Create a separate Studio configuration:

```tsx filename="flexkit.studio.tsx"
import { defineConfig } from '@flexkit/studio';
import { Desk } from '@flexkit/desk';
import { AssetManager } from '@flexkit/asset-manager';
import { Explorer } from '@flexkit/explorer';
import { AI } from '@flexkit/ai';
import project from './flexkit.config';

export default defineConfig({
  ...project,
  extensions: [Desk(), AssetManager(), Explorer(), AI()],
});
```

<Callout type="info">
  **Important**: Replace `'your-project-id'` with the unique project ID of your Flexkit project.
</Callout>

`local` fields like product names, descriptions, prices, and category labels use the currently selected scope in Studio. If a local field has no value in the selected scope, the default scope value is used.

### Create the API route handler and Studio page

Create a new API route handler to serve the Flexkit API and a Studio page to render the Flexkit Studio interface. Create the following file structure:

<FileTree>
  <FileTree.Folder name="app" open>
    <FileTree.Folder name="api" open>
      <FileTree.Folder name="flexkit" open>
        <FileTree.Folder name="[...path]" open>
          <FileTree.File name="route.ts" active />
        </FileTree.Folder>
      </FileTree.Folder>
    </FileTree.Folder>
    <FileTree.Folder name="studio" open>
      <FileTree.Folder name="[[...index]]" open>
        <FileTree.File name="page.tsx" active />
      </FileTree.Folder>
    </FileTree.Folder>
  </FileTree.Folder>
</FileTree>

```tsx filename="app/api/flexkit/[...path]/route.ts"
import { createFlexkitApiHandler } from '@flexkit/studio/nextjs';
import { NextResponse } from 'next/server';
import { cookies, headers } from 'next/headers';

const flexkitHandler = createFlexkitApiHandler({
  NextResponse,
  cookies,
  headers,
});

export const runtime = 'nodejs';

export const { GET, POST, PUT, PATCH, DELETE } = flexkitHandler;
```

<br />
```tsx filename="app/studio/[[...index]]/page.tsx" 'use client';

import { JSX } from 'react';
import '@flexkit/studio/styles.css';
import '@flexkit/desk/styles.css';
import '@flexkit/asset-manager/styles.css';
import '@flexkit/explorer/styles.css';
import '@flexkit/ai/styles.css';
import { FlexkitStudio } from '@flexkit/studio';
import config from '../../../flexkit.studio';

export default function Page(): JSX.Element | null {
  return <FlexkitStudio config={config} />;
}
```

### Deploy your data schema

<Callout>Install the [Flexkit CLI](/docs/cli) to deploy your data schema.</Callout>

```bash
flexkit login
flexkit whoami
flexkit deploy
```

### Run Your Project

Start the development server:

**pnpm**

```sh
pnpm dev
```

**npm**

```sh
npm run dev
```

**yarn**

```sh
yarn dev
```

**bun**

```sh
bun dev
```

Open your browser and navigate to `http://localhost:3000/studio`

</Steps>

## Confirm your first success

Sign into Studio with the account that has access to the configured project. Open Desk, create a Category and Product, save, and reopen the record. Open Explorer and run the [tutorial read](/docs/api/graphql/queries). The record ID and global SKU should agree with the saved record.

If the UI loads but data does not, check the project ID, completed schema deployment, role/spaces, and API handler route. Missing styles usually indicate an omitted extension stylesheet. Continue with [your first workflow](/docs/getting-started/first-workflow), then [production deployment](/docs/deployment).


---

[View full sitemap](/docs/sitemap.md)
