Skip to main content

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 to Next.js
# 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-nextjs
pnpm create next-app clerk-nextjs --yes
cd clerk-nextjs
yarn create next-app clerk-nextjs --yes
cd clerk-nextjs
bunx create-next-app clerk-nextjs --yes
cd clerk-nextjs

Install @clerk/nextjs

The Clerk Next.js SDKNext.js Icon 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/nextjs
pnpm add @clerk/nextjs
yarn add @clerk/nextjs
bun add @clerk/nextjs

Add clerkMiddleware() to your app

clerkMiddleware()Next.js Icon grants you access to user authentication state throughout your app. To add clerkMiddleware() to your app, follow these steps:

Important

If you're using Next.js ≤15, name your file middleware.ts instead of proxy.ts. The code itself remains the same; only the filename changes.

  1. Create a proxy.ts file.

    • If you're using the /src directory, create proxy.ts in the /src directory.
    • If you're not using the /src directory, create proxy.ts in the root directory.
  2. In your proxy.ts file, export the clerkMiddleware() 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/(.*)',
      ],
    }
  3. 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.
app/layout.tsx
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 collapsedconst 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:

Run your project

Run your project with the following command:

npm run dev
pnpm run dev
yarn dev
bun run dev

Create your first user

  1. Visit your app's homepage at http://localhost:3000.
  2. 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

What did you think of this content?

Last updated on