---
title: "Payload CMS — Installation & Setup"
aliases: [payload-cms, payloadcms-install, payload-nextjs]
tags: [payload-cms, nextjs, cms, headless, typescript]
sources: [raw/Installation  Documentation.md]
created: 2026-05-15
updated: 2026-05-15
---

## Payload CMS — Installation & Setup

[Payload CMS](https://payloadcms.com) is a TypeScript-first headless CMS that runs **inside** a Next.js app (App Router). No separate backend process — Payload lives in your `/app/(payload)/` route group.

## Requirements

| Requirement | Version |
|-------------|---------|
| Node.js | 20.9.0+ |
| Next.js | `15.2.9–15.2.x` / `15.3.9–15.3.x` / `15.4.11–15.4.x` / `16.2.2+` |
| Package manager | pnpm (preferred), npm, yarn 2+ (yarn 1.x **not supported**) |
| Database | MongoDB, Postgres, or SQLite |

> **Not all Next.js 15/16 patch releases are compatible** — use only the version ranges above.

## Quickstart (new project)

```bash
npx create-payload-app
```

Follow the prompts — you get a working Payload app in a new folder.

## Add to Existing Next.js App

### 1. Install packages

```bash
pnpm i payload @payloadcms/next

# Optional but common:
pnpm i @payloadcms/richtext-lexical   # Rich text editor
pnpm i sharp                           # Image resize/crop/focal point
pnpm i graphql                         # Only if using GraphQL API
```

**Database adapter — pick one:**

```bash
pnpm i @payloadcms/db-mongodb    # MongoDB
pnpm i @payloadcms/db-postgres   # Postgres
pnpm i @payloadcms/db-sqlite     # SQLite
```

> npm users: `npm i --legacy-peer-deps`

### 2. Copy Payload files into `/app`

Copy the `(payload)` route group from [Blank Template](https://github.com/payloadcms/payload/tree/3.x/templates/blank/src/app/%28payload%29):

```
app/
├── (payload)/      ← Payload admin + API routes (never edit these)
└── (my-app)/       ← Your existing frontend (rename freely)
```

Move existing frontend files into a new route group (e.g. `(frontend)`). Payload files import from `@payloadcms/next` — set once, never revisited.

### 3. Wrap Next.js config with `withPayload`

```js
// next.config.mjs  ← must be ESM (.mjs or "type":"module" in package.json)
import { withPayload } from '@payloadcms/next/withPayload'

const nextConfig = {
  // your config
}

export default withPayload(nextConfig)
```

> Payload is fully ESM — `require()` won't work. Use `.mjs` extension or set `"type": "module"`.

### 4. Create `payload.config.ts`

```ts
import sharp from 'sharp'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { buildConfig } from 'payload'

export default buildConfig({
  editor: lexicalEditor(),
  collections: [],
  secret: process.env.PAYLOAD_SECRET || '',
  db: mongooseAdapter({
    url: process.env.DATABASE_URL || '',
  }),
  sharp,
})
```

Register the config path in `tsconfig.json`:

```json
{
  "compilerOptions": {
    "paths": {
      "@payload-config": ["./payload.config.ts"]
    }
  }
}
```

### 5. Start & create first user

```bash
pnpm dev
# → http://localhost:3000/admin
```

## Key Takeaways

- Payload runs **inside Next.js** — no separate server; admin panel at `/admin`
- Only specific Next.js patch versions are compatible — check the list before upgrading
- `(payload)` route group files are **never edited** — they're boilerplate from the template
- `withPayload` in `next.config` must be ESM — use `.mjs` or `"type":"module"`
- `PAYLOAD_SECRET` must be a strong random string (used to sign tokens)
- `sharp` is optional — only needed for image manipulation in Upload collections
- `@payloadcms/richtext-lexical` is optional — only needed if using Rich Text fields

## Related

- [[wiki/tech-patterns/nextjs-fastapi-fullstack|Next.js + FastAPI Fullstack]] — alternative when you need a separate Python backend
- [[wiki/tech-patterns/react-vite-typescript|React + Vite + TypeScript]] — SPA alternative without SSR/CMS
- [[wiki/tech-patterns/azure-ad-msal-auth|Azure AD / MSAL Auth]] — if Payload needs SSO instead of built-in auth

## Sources

- `raw/Installation  Documentation.md` — clipped from https://payloadcms.com/docs/getting-started/installation
