--- 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