Next.js Quickstart (App Router)
Hand this prompt to your agent to add auth to your app with the Clerk CLI. No need to leave your terminal or copy and paste API keys.
# Add Clerk Authentication to Next.js
Set up Clerk authentication in this Next.js project with the Clerk CLI.
```bash
npx -y clerk@latest init
```
## Why the CLI
`clerk init` needs no Clerk account. It detects agent environments and runs in agent mode — non-interactive, so nothing blocks waiting on the user and no keys pass through the conversation. Signed out, it runs keyless: it provisions a claimable app, writes dev keys to `.env.local`, and wires up the SDK, provider, middleware, and auth routes. Signing in later claims that app.
Keyless apps stay configurable from the CLI — `clerk enable orgs` and `clerk config patch` work before claiming; billing and some auth settings need claiming first.
In agent mode it also installs Clerk agent skills globally into `~/.agents/skills/`, linked into supported agent tools.
## Quick Setup
Before running any commands, present the user with a preliminary setup checklist:
```
Here's what I'll do to get you set up with Clerk.
1. Set up Clerk in this project, or scaffold a new Next.js app with Clerk if this directory is empty
2. Start your app with Clerk installed.
3. Optionally sign in later to claim the app.
Shall I proceed?
```
## Step 1: Run the Clerk CLI
No install needed — run `clerk` commands through the project's package runner: `npx -y clerk@latest <command>`, `pnpm dlx clerk@latest`, `bunx clerk@latest`, or `yarn dlx clerk@latest` (yarn 2+ only). If `clerk` is already installed, run `clerk update --yes` and use it directly.
## Step 2: Sign in to Clerk (optional)
Only sign in if the user wants to use an existing Clerk account or app:
```bash
npx -y clerk@latest auth login
```
Pause while the user completes the login flow. Do not list apps or ask which app to use.
## Step 3: Initialize Clerk
If this is an existing Next.js project, run:
```bash
clerk init
```
`clerk init` is the default setup action, signed in or not. It detects the framework and package manager and applies the Next.js setup described above. Do not pass `--framework` or `--pm` for existing projects unless the user explicitly wants to override detection or the CLI asks for those values.
If the directory is empty, ask the user which package manager they want to use. If they have no preference, use npm. Then scaffold a fresh Next.js app:
```bash
clerk init --framework next --pm <package-manager>
```
If the directory has a leftover lockfile, match the package manager to it (`pnpm-lock.yaml` → `pnpm`, `yarn.lock` → `yarn`, `bun.lock`/`bun.lockb` → `bun`, `package-lock.json` → `npm`) instead of asking.
Do not add `--app` or list apps unless the user wants to link a specific existing application: `clerk init --app <application_id>` (find IDs with `clerk apps list --json`, then ask which to use).
## Step 4: Fall back to manual setup when init is incomplete
Only do this if `clerk init` has already run and failed — do not start here.
If `clerk init` reports an error or does not finish the setup, finish manually: install `@clerk/nextjs`, create a middleware file that calls `clerkMiddleware()` from `@clerk/nextjs/server` (see Critical rules for the filename), and wrap the app with `<ClerkProvider>` as shown in Step 5.
## Step 5: Ensure clear auth controls are visible
Make sure the app has clear sign-in, sign-up, and signed-in user controls so the user can create and recognize their first account. Integrate them into the existing layout or navigation so they feel natural.
Use Clerk components from `@clerk/nextjs` such as `SignInButton`, `SignUpButton`, `Show`, and `UserButton`. Show sign-in and sign-up actions when signed out, and a user button when signed in. For example, in `app/layout.tsx`:
```tsx
import { ClerkProvider, SignInButton, SignUpButton, Show, UserButton } from '@clerk/nextjs'
import './globals.css'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ClerkProvider>
<header>
<Show when="signed-out">
<SignInButton />
<SignUpButton />
</Show>
<Show when="signed-in">
<UserButton />
</Show>
</header>
{children}
</ClerkProvider>
</body>
</html>
)
}
```
If clear auth controls already exist, reuse or adapt them instead of duplicating them.
## Step 6: Verify the setup
After `clerk init` completes, run:
```bash
npx -y clerk@latest doctor
```
Then start the app, confirm the sign-in, sign-up, and signed-in user controls are visible, test the sign-in and sign-up flow, and fix any issues reported by the CLI.
## Step 7: If using shadcn/ui
If `components.json` exists in the project root and Clerk components are used, install `@clerk/ui` with the project's package manager:
```bash
npm install @clerk/ui
```
Apply the theme in `app/layout.tsx`: import `shadcn` from `@clerk/ui/themes` and set `appearance={{ theme: shadcn }}` on `<ClerkProvider>`.
Add to global CSS:
```css
@import '@clerk/ui/themes/shadcn.css';
```
## Critical rules
- Setup is `clerk init` (`npx -y clerk@latest init`), signed in or not. Do not install `@clerk/nextjs` or hand-write setup unless it has run and failed
- `clerk init` writes `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` to `.env.local`. Do not ask the user to copy keys
- Name the middleware file by the `next` version in `package.json`: `proxy.ts` on Next.js 16+, `middleware.ts` on 15 and below. The contents are identical; `clerk init` creates it
- `auth()` from `@clerk/nextjs/server` is async. Always `await auth()`
- `ClerkProvider` goes inside `<body>`, not wrapping `<html>`
- Never expose `CLERK_SECRET_KEY` in client code
- Use `@clerk/nextjs`, not `@clerk/clerk-react`
- Do not read or print existing environment variable files; ask the user for any missing non-sensitive configuration
Docs: https://clerk.com/docs/cli https://clerk.com/docs/llms.txt
## After Setup
Have the user sign up as their first test user in the nav. After signup succeeds and a profile icon appears, congratulate them. If a "Configure your application" callout appears, tell them to click it. Then recommend exploring: Organizations (https://clerk.com/docs/guides/organizations/overview), Components (https://clerk.com/docs/reference/components/overview), Dashboard (https://dashboard.clerk.com/).Or set up Clerk yourself by following the step-by-step instructions.
Step-by-step setup instructions
Create a new Next.js app
If you don't already have a Next.js app, run the following commands to create a new one.
npm create next-app@latest clerk-nextjs -- --yes
cd clerk-nextjspnpm create next-app clerk-nextjs --yes
cd clerk-nextjsyarn create next-app clerk-nextjs --yes
cd clerk-nextjsbunx create-next-app clerk-nextjs --yes
cd clerk-nextjsInstall @clerk/nextjs
The Clerk Next.js SDK gives you access to prebuilt components, hooks, and helpers to make user authentication easier.
Run the following command to install the SDK:
npm install @clerk/nextjspnpm add @clerk/nextjsyarn add @clerk/nextjsbun add @clerk/nextjsSet your Clerk API keys
Add the following keys to your .env file. These keys can always be retrieved from the API keys page in the Clerk Dashboard.
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEYAdd clerkMiddleware() to your app
clerkMiddleware()clerkMiddleware() to your app, follow these steps:
-
Create a
proxy.tsfile.- If you're using the
/srcdirectory, createproxy.tsin the/srcdirectory. - If you're not using the
/srcdirectory, createproxy.tsin the root directory.
- If you're using the
-
In your
proxy.tsfile, export theclerkMiddleware()helper:proxy.ts import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware() export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', // Always run for Clerk-specific frontend API routes '/__clerk/(.*)', ], } -
By default,
clerkMiddleware()will not protect any routes. All routes are public and you must opt-in to protection. To require a signed-in user, protect resources close to where they're used, as shown in the guide on protecting content.
Add <ClerkProvider> and Clerk components to your app
The <ClerkProvider> component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider> to make authentication globally accessible. See the reference docs for other configuration options.
Copy and paste the following code into your layout.tsx file. This:
- Adds the
<ClerkProvider>component to your app's layout, providing Clerk's authentication context to your app. - Creates a header with Clerk's prebuilt components to allow users to sign in and out, and display different content for signed-in and signed-out users.
import type { Metadata } from 'next'
import { ClerkProvider, Show, SignInButton, SignUpButton, UserButton } from '@clerk/nextjs'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'
14 lines collapsed
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
})
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
})
export const metadata: Metadata = {
title: 'Clerk Next.js Quickstart',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en" className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}>
<body className="min-h-full flex flex-col">
<ClerkProvider>
<header className="flex justify-end items-center p-4 gap-4 h-16">
<Show when="signed-out">
<SignInButton />
<SignUpButton>
<button className="bg-[#6c47ff] text-white rounded-full font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 cursor-pointer">
Sign Up
</button>
</SignUpButton>
</Show>
<Show when="signed-in">
<UserButton />
</Show>
</header>
{children}
</ClerkProvider>
</body>
</html>
)
}This example uses the following components:
- <Show when="signed-in">: Children of this component can only be seen while signed in.
- <Show when="signed-out">: Children of this component can only be seen while signed out.
- <UserButton />: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options.
- <SignInButton />: An unstyled component that links to the sign-in page. In this example, since no props or environment variables are set for the sign-in URL, this component links to the Account Portal sign-in page.
- <SignUpButton />: An unstyled component that links to the sign-up page. In this example, since no props or environment variables are set for the sign-up URL, this component links to the Account Portal sign-up page.
Run your project
Run your project with the following command:
npm run devpnpm run devyarn devbun run devCreate your first user
- Visit your app's homepage at http://localhost:3000.
- Select "Sign up" on the page and authenticate to create your first user.
Next steps
Explore the most relevant next steps for your SDK using the following guides.
Prebuilt components
Learn how to add Clerk's prebuilt authentication and user-management UI to your app.
Build custom flows
Learn how to build custom user interfaces entirely from scratch using the Clerk API.
Read user data
Learn how to use Clerk's helpers to read user data in your app.
Customization & localization
Learn how to customize and localize Clerk components.
More to explore
Explore additional Clerk features that help you build, manage, and grow your application.
- Organizations - Organizations are shared accounts that let teams collaborate, manage members and roles, and control access to shared resources.
- Billing - Billing enables you to manage subscriptions, free trials, payments, plans, and billing-related webhook events for B2C and B2B applications.
- Waitlist - Waitlist lets you collect signups and control access to new products or features before launch through a simple, integrated workflow.
Feedback
Last updated on