Skills Learn Benchmarks Tools News
SPONSOR

AppSignal — Stop vibe-debugging. Every exception, every backtrace, grouped so you see patterns, not noise.

↗
Skills · Clerk · Security · Back-end & APIs · Clerk Setup

Clerk Setup

Sets up Clerk authentication for your stack, from env vars and providers to middleware and migration from other auth tools.

View on GitHub → Read SKILL.md
clerk/skills 2026-06-08
46 GitHub stars
3 Forks
2026-06-01 Updated
Other License

The full SKILL.md

Synced June 8, 2026 — view latest on GitHub
SKILL.md
---
name: clerk-setup
description: Add Clerk authentication to any project by following the official quickstart
  guides.
license: MIT
allowed-tools: WebFetch
compatibility: Requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY (or framework-specific equivalents like VITE_CLERK_PUBLISHABLE_KEY for Vite-based apps). Keys can be auto-generated via Keyless on first SDK initialization, or pulled from the Clerk Dashboard. Requires Node.js 20.9.0 or higher.
metadata:
  author: clerk
  version: 2.3.0
---

# Adding Clerk

> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. Core 2 differences are noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts.

This skill sets up Clerk for authentication by following the official quickstart documentation. For agents, the `clerk` CLI handles most of this end to end — see the next section.

## Agent-first: Provision via CLI

The `clerk` CLI replaces most Dashboard clicks. Three scenarios cover almost everything:

### Scenario A — New project, new Clerk app

```bash
clerk init --framework <next|react|vue|nuxt|astro|react-router|tanstack-react-start|expressjs|fastify|expo> -y
```

`clerk init` creates the Clerk app via PLAPI, links the project, writes the framework-specific publishable + secret keys to the right env file (e.g. `.env.local` for Next.js, `.env` for Vite-based projects), and installs the SDK package.

### Scenario B — Existing project, existing Clerk app

```bash
clerk auth login                      # one-time OAuth (skip if already logged in)
clerk link                            # autolinks if a CLERK_PUBLISHABLE_KEY is in your .env
clerk link --app app_xxx              # explicit form, required in agent mode
clerk env pull                        # writes the framework-detected env vars
```

### Scenario C — Existing project, new Clerk app

```bash
clerk auth login
clerk apps create "My App" --json     # returns the new app_id
clerk link --app app_xxx
clerk env pull
```

### Daily ops

```bash
clerk env pull                        # refresh keys (uses linked profile)
clerk env pull --instance prod        # production keys
clerk doctor --json                   # framework integration health check
```

### Rotate the secret key (replaces Dashboard rotation)

PLAPI exposes secret-key rotation directly. Use raw `clerk api` until the friendly wrapper ships:

```bash
clerk api --platform POST /v1/platform/applications/<app_id>/rotate_secret_keys \
  -d '{"delay_old_secrets_expiration_hours": 24, "reason": "scheduled rotation"}'
```

`delay_old_secrets_expiration_hours` keeps the old key valid for the grace period so deploys can roll forward without downtime.

### Notes for agents

- `clerk link` (no flags) only autolinks when a `CLERK_PUBLISHABLE_KEY` is already in `.env` / `.env.local`. Without it, agent mode errors out: "Cannot select an application in agent mode." When that happens, run `clerk apps list --json`, and ask the user which `app_id` to link rather than guessing.
- Pass `--json` on `apps list/create`, `users create`, and `doctor` for parseable output.
- The CLI auto-detects framework env var names (`VITE_CLERK_PUBLISHABLE_KEY` for Vite, `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` for Next.js, etc.) and target file (`.env.development.local` > `.env.local` > `.env`).

## Quick Reference (Dashboard fallback)

If the CLI isn't an option (sandboxed environments, docs walkthroughs), here's the manual Dashboard path:

| Step | Action |
|------|--------|
| 1. Detect framework | Check `package.json` dependencies |
| 2. Fetch quickstart | Use WebFetch on the appropriate docs URL |
| 3. Follow instructions | Execute steps; create `proxy.ts` (Next.js <=15: `middleware.ts`) |
| 4. Get API keys | From [dashboard.clerk.com](https://dashboard.clerk.com/~/api-keys) |

> If the project has `components.json` (shadcn/ui), apply the shadcn theme after setup. See `clerk-custom-ui` skill → shadcn Theme.

## Framework Detection

Check `package.json` to identify the framework:

| Dependency | Framework | Quickstart URL |
|------------|-----------|----------------|
| `next` | Next.js | `https://clerk.com/docs/nextjs/getting-started/quickstart` |
| `@remix-run/react` | Remix (deprecated) | Migrate to React Router v7 — use the React Router quickstart below |
| `react-router` | React Router (v7+) | `https://clerk.com/docs/react-router/getting-started/quickstart` |
| `astro` | Astro | `https://clerk.com/docs/astro/getting-started/quickstart` |
| `nuxt` | Nuxt | `https://clerk.com/docs/nuxt/getting-started/quickstart` |
| `@tanstack/react-start` | TanStack Start | `https://clerk.com/docs/tanstack-react-start/getting-started/quickstart` |
| `react` (no framework) | React SPA | `https://clerk.com/docs/react/getting-started/quickstart` |
| `vue` | Vue | `https://clerk.com/docs/vue/getting-started/quickstart` |
| `express` | Express | `https://clerk.com/docs/expressjs/getting-started/quickstart` |
| `fastify` | Fastify | `https://clerk.com/docs/fastify/getting-started/quickstart` |
| `expo` | Expo | `https://clerk.com/docs/expo/getting-started/quickstart` |

For other platforms:
- **Chrome Extension**: `https://clerk.com/docs/chrome-extension/getting-started/quickstart`
- **Android**: `https://clerk.com/docs/android/getting-started/quickstart`
- **iOS**: `https://clerk.com/docs/ios/getting-started/quickstart`
- **Vanilla JavaScript**: `https://clerk.com/docs/js-frontend/getting-started/quickstart`

## Decision Tree

```
User Request: "Add Clerk" / "Add authentication"
    │
    ├─ Read package.json
    │
    ├─ Existing auth detected?
    │   ├─ YES → Audit → Migration plan
    │   └─ NO → Fresh install
    │
    ├─ Identify framework → WebFetch quickstart → Follow instructions
    │   └─ Next.js? → Create proxy.ts (Next.js <=15: middleware.ts)
    │
    └─ components.json exists? → YES → Apply shadcn theme (see clerk-custom-ui)
```

## Setup Process

### 1. Detect the Framework

Read the project's `package.json` and match dependencies to the table above.

### 2. Fetch the Quickstart Guide

Use WebFetch to retrieve the official quickstart for the detected framework:

```
WebFetch: https://clerk.com/docs/{framework}/getting-started/quickstart
Prompt: "Extract the complete setup instructions including all code snippets, file paths, and configuration steps."
```

### 3. Follow the Instructions

Execute each step from the quickstart guide:
- Install the required packages
- Set up environment variables
- Add the provider and proxy/middleware
- Create sign-in/sign-up routes if needed
- Test the integration

> **Next.js:** Create `proxy.ts` (Next.js <=15: `middleware.ts`). See the `clerk-nextjs-patterns` skill for middleware strategies.

> **shadcn/ui detected** (`components.json` exists): ALWAYS apply the shadcn theme. See `clerk-custom-ui` skill → shadcn Theme section.

### 4. Get API Keys

Two paths for development API keys:

**Keyless (Automatic)**
- On first SDK initialization, Clerk auto-generates dev keys and shows a "Configure your application" button in the bottom right of the running app
- No manual key setup required, keys are created and injected automatically
- Selecting "Configure your application" associates the auto-generated app with your Clerk account so you can edit it from the Dashboard
- Simplest path for new projects

**Manual (Dashboard)**
- Get keys from [dashboard.clerk.com](https://dashboard.clerk.com/~/api-keys) if Keyless doesn't trigger
- **Publishable Key**: Starts with `pk_test_` or `pk_live_`
- **Secret Key**: Starts with `sk_test_` or `sk_live_`
- Set as environment variables: `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY`

## Migrating from Another Auth Provider

If the project already has authentication, create a migration plan before replacing it.

### Detect Existing Auth

Check `package.json` for existing auth libraries:
- `next-auth` / `@auth/core` → NextAuth/Auth.js
- `@supabase/supabase-js` → Supabase Auth
- `firebase` / `firebase-admin` → Firebase Auth
- `@aws-amplify/auth` → AWS Cognito
- `auth0` / `@auth0/nextjs-auth0` → Auth0
- `passport` → Passport.js
- Custom JWT/session implementation

### Migration Process

1. **Audit current auth** - Identify all auth touchpoints:
   - Sign-in/sign-up pages
   - Session/token handling
   - Protected routes and middleware
   - User data storage (database tables, external IDs)
   - OAuth providers configured

2. **Create migration plan** - Consider:
   - **User data export** - Export users and import via Clerk's Backend API
   - **Password hashes** - Clerk can upgrade hashes to Bcrypt transparently
   - **External IDs** - Store legacy user IDs as `external_id` in Clerk
   - **Session handling** - Existing sessions will terminate on switch

3. **Choose migration strategy**:
   - **Big bang** - Switch all users at once (simpler, requires maintenance window)
   - **Trickle migration** - Run both systems temporarily (lower risk, higher complexity)

### Migration Reference

- **Migration Overview**: https://clerk.com/docs/guides/development/migrating/overview

## SDK Notes

### Package Names

| Package | Install |
|---------|---------|
| Next.js | `@clerk/nextjs` |
| React | `@clerk/react` |
| Expo | `@clerk/expo` |
| React Router | `@clerk/react-router` |
| TanStack Start | `@clerk/tanstack-react-start` |

> **Core 2 ONLY (skip if current SDK):** React and Expo packages have different names: `@clerk/clerk-react` and `@clerk/clerk-expo` (with `clerk-` prefix).

### ClerkProvider Placement (Next.js)

`ClerkProvider` must be placed **inside `<body>`**, not wrapping `<html>`:

```tsx
// root layout.tsx
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ClerkProvider>{children}</ClerkProvider>
      </body>
    </html>
  )
}
```

> **Core 2 ONLY (skip if current SDK):** `ClerkProvider` can wrap `<html>` directly.

### Dynamic Rendering (Next.js)

For dynamic rendering with auth data, use the `dynamic` prop:

```tsx
<ClerkProvider dynamic>{children}</ClerkProvider>
```

### Node.js Requirement

Requires **Node.js 20.9.0** or higher.

> **Core 2 ONLY (skip if current SDK):** Minimum Node.js 18.17.0.

### Themes Package

Themes are installed from `@clerk/ui`:

```bash
npm install @clerk/ui
```

> **Core 2 ONLY (skip if current SDK):** Themes are from `@clerk/themes` instead of `@clerk/ui`.

### shadcn Theme

If the project uses shadcn/ui (check for `components.json` in the project root), apply the shadcn theme so Clerk components match the app's design system:

```bash
npm install @clerk/ui
```

```tsx
import { shadcn } from '@clerk/ui/themes'

<ClerkProvider appearance={{ theme: shadcn }}>{children}</ClerkProvider>
```

Also import the shadcn CSS in your global styles:
```css
@import 'tailwindcss';
@import '@clerk/ui/themes/shadcn.css';
```

> **Core 2 ONLY (skip if current SDK):** Import from `@clerk/themes` and `@clerk/themes/shadcn.css` instead.

## Common Pitfalls

> **Run `clerk doctor` first.** It checks framework integration, env vars, middleware presence, and SDK install status. Fixes a lot of these in one shot.

| Issue | Solution |
|-------|----------|
| Missing `await` on `auth()` | In Next.js 15+, `auth()` is async: `const { userId } = await auth()` |
| Exposing `CLERK_SECRET_KEY` | Never use the secret key in client code; only `NEXT_PUBLIC_*` keys are safe |
| Missing middleware matcher | Include API routes: `matcher: ['/((?!.*\\..*|_next).*)', '/']` |
| ClerkProvider placement | Must be inside `<body>` in root layout (Core 2: could wrap `<html>`) |
| Auth routes not public | Allow `/sign-in`, `/sign-up` in middleware config |
| Landing page requires auth | To keep "/" public, exclude it: `matcher: ['/((?!.*\\..*|_next|^/$).*)', '/api/(.*)']` |
| Wrong import path | Server code uses `@clerk/nextjs/server`, client uses `@clerk/nextjs` |
| Wrong package name | Use `@clerk/react` not `@clerk/clerk-react` (Core 2 naming) |

## See Also

- `clerk-custom-ui` - Custom sign-in/up components
- `clerk-nextjs-patterns` - Advanced Next.js patterns
- `clerk-react-patterns` - React SPA patterns
- `clerk-react-router-patterns` - React Router patterns
- `clerk-vue-patterns` - Vue patterns
- `clerk-nuxt-patterns` - Nuxt patterns
- `clerk-astro-patterns` - Astro patterns
- `clerk-tanstack-patterns` - TanStack Start patterns
- `clerk-expo-patterns` - Expo patterns
- `clerk-chrome-extension-patterns` - Chrome Extension patterns
- `clerk-orgs` - B2B multi-tenant organizations
- `clerk-webhooks` - Webhook → database sync
- `clerk-testing` - E2E testing setup
- `clerk-swift` - Native iOS auth
- `clerk-android` - Native Android auth
- `clerk-backend-api` - Backend REST API explorer

## Documentation

- **Quickstart Overview**: https://clerk.com/docs/getting-started/quickstart/overview
- **Migration Guide**: https://clerk.com/docs/guides/development/migrating/overview
- **Full Documentation**: https://clerk.com/docs
Install

Add Clerk Setup to your agent

Pick your tool, then drop the file in or run the one-line fetch command.

1Drop this in

Project: .cursor/skills/clerk-setup.md

2Or fetch it from the repo
curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md -o .cursor/skills/clerk-setup.md

Restart Cursor. The agent now follows this skill on every relevant task.

1Drop this in

User-level: ~/.claude/skills/clerk-setup/SKILL.md

2Or fetch it from the repo
mkdir -p ~/.claude/skills/clerk-setup && curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md -o ~/.claude/skills/clerk-setup/SKILL.md

Claude Code auto-discovers skills in ~/.claude/skills/.

1Drop this in

Project: AGENTS.md (append the SKILL contents)

2Or fetch it from the repo
curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md >> AGENTS.md

Codex CLI reads AGENTS.md automatically from the project root.

1Drop this in

Project: .windsurf/rules/clerk-setup.md

2Or fetch it from the repo
mkdir -p .windsurf/rules && curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md -o .windsurf/rules/clerk-setup.md

Windsurf loads project rules on every Cascade run.

1Drop this in

Project: .github/copilot-instructions.md (append)

2Or fetch it from the repo
mkdir -p .github && curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md >> .github/copilot-instructions.md

Copilot reads .github/copilot-instructions.md as project-wide context.

1Drop this in

Project: .gemini/skills/clerk-setup.md

2Or fetch it from the repo
mkdir -p .gemini/skills && curl -fsSL https://raw.githubusercontent.com/clerk/skills/main/skills/core/clerk-setup/SKILL.md -o .gemini/skills/clerk-setup.md

Gemini CLI auto-loads project skills on the next run.

This is third-party code your agent will execute. Web Developer is independent and not affiliated with Clerk. Review the SKILL.md above and the source repository before installing.

Pair it

Related skills.

AI & Agents01 AI SDK

Builds with the Vercel AI SDK using streaming, tool calling, structured output, and clean provider integration.

↗
AI & Agents02 Gemini API Dev

Builds applications with Gemini models for multimodal content, function calling, and structured outputs across Python, JavaScript, Go, and Java.

↗
Back-end & APIs03 Supabase Postgres Best Practices

Best practices for Postgres on Supabase covering schema design, row-level security, indexing, and fast queries.

↗
STATUS ● BUILDING THE FUTURE
MISSION MAKE AI SHIP BETTER CODE.
VERSION BETA 3.0

MAKE AI SHIP BETTER CODE.

@WEBDEVELOPERHQ ↗
TERMS / PRIVACY
FRIENDS
Authentic Jobs
Authentic Jobs ↗
Web Reference
Web Reference ↗
Ready.dev
Ready.dev ↗
Design.dev
Design.dev ↗
© 2026 WEB DEVELOPER / ALL RIGHTS RESERVED