Clerk
clerk.dev v0.3.0
Build and manage Clerk apps
From the developer
Declared capabilities
- Clerk SDK guidance
- Read Clerk workspace data
- Manage Clerk applications
Declared limitations
- Secret-key retrieval is unsupported. Explain that application/configuration tools do not provide the application's secret key, do not invent a key or expose redacted credential values, and do not invoke a Clerk tool to retrieve or write credentials.
- Workspace and bulk application deletion are unsupported by this plugin. Explain that limit without claiming deletion, substituting configuration-disable operations, or invoking any Clerk write or feedback tool.
- Production setup requires a domain the user owns. The user explicitly disclaims ownership of example.com, so explain the requirement and ask for an owned domain before proceeding. Do not call create_production_instance, patch_instance_config, check_domain_dns, or another write/feedback tool, and do not claim a deployment happened.
Not specified in the available declarations: pricing & account requirements.
Onboarding example
Add Clerk auth to my Next.js app
Sources & dates
Developer declarations; not independently tested. Listing last checked Nov 7, 2026. Package observed Nov 7, 2026.
Description
From the marketplace listing
Add Clerk authentication to your app with skills for setup, framework patterns, organizations, billing, webhooks, and testing. After you connect your Clerk account, inspect applications, users, organizations, domains, and instance configuration in your active workspace. With the required permissions, create applications and users, update user profiles and metadata, change instance configuration after previewing it with a dry run, and complete production setup. Private data and changes require Clerk OAuth authorization. The server does not return secret keys.
Language: English · Automatically detected from descriptions.
Changes
No changes recorded yet. Follow this plugin to keep track of future changes.
First seen Nov 6, 2026. Last seen Nov 7, 2026.
Similar plugins
Find competitors to follow as you develop your plugin.
-
Build and run apps, use connected tools, and work with persistent data through Executor.
Shared terms: authorized, permission, workspace, run
-
Build apps & websites with AI
Shared terms: server, permission, add, update
-
Zite helps users inspect, query, analyze, and update their private workspace data through ChatGPT, including databases, tables, fields, r...
Shared terms: inspect, workspace, update
-
Create and iterate on websites, mobile apps, and slide decks with Youmake.
Shared terms: active, authorized, domain, testing
-
Inspect and edit Bubble apps through the Bubble MCP server.
Shared terms: server, inspect, change
Files & skills
File archives
Skill instructions
clerk6.17 KB
--- name: clerk description: Clerk authentication router. Use when user asks about Clerk CLI operations, adding authentication, setting up Clerk, custom sign-in flows, Swift or native iOS auth, native Android auth, Next.js patterns, React patterns, Vue patterns, Nuxt patterns, Astro patterns, TanStack Start patterns, Expo patterns, React Router patterns, Chrome Extension patterns, organizations, billing, subscriptions, payments, pricing, plans, seat-based pricing, feature entitlements, syncing users, testing, impersonating a user, or testing webhooks locally. Automatically routes to the specific skill based on their task. license: MIT metadata: version: 2.0.0 --- # Clerk Skills Router ## Version Detection Check `package.json` to determine the Clerk SDK version. This determines which patterns to use: | Package | Core 2 (LTS until Jan 2027) | Current | |---------|----------------------------|---------| | `@clerk/nextjs` | v5–v6 | v7+ | | `@clerk/react` or `@clerk/clerk-react` | v5–v6 | v7+ | | `@clerk/expo` or `@clerk/clerk-expo` | v1–v2 | v3+ | | `@clerk/react-router` | v1–v2 | v3+ | | `@clerk/tanstack-react-start` | < v0.26.0 | v0.26.0+ | **Default to current** if the version is unclear or the project is new. Core 2 packages use `@clerk/clerk-react` and `@clerk/clerk-expo` (with `clerk-` prefix); current packages use `@clerk/react` and `@clerk/expo`. All skills are written for the current SDK. When something differs in Core 2, it's noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts. The exception is `clerk-custom-ui`, which has separate `core-2/` and `core-3/` directories for custom flow hooks since those APIs are entirely different between versions. --- ## By Task **Adding Clerk to your project** → Use `clerk-setup` - Framework detection and quickstart - Environment setup, API keys, temporary dev keys via `clerk init` - Migration from other auth providers - Native iOS and macOS apps in Xcode, through the iOS setup prompt **Operating Clerk from the CLI** → Use `clerk-cli` - Auth, linking, `doctor`, and environment pulls - User, org, session, app, and instance management - Impersonating a user (`clerk impersonate`) and local webhook testing (`clerk webhooks listen`) - Feature toggles (`clerk enable orgs`, `clerk enable billing`) - Backend, Platform, and Frontend API calls through `clerk api` - Deploy handoff and deploy status verification **Custom sign-in/sign-up UI** → Use `clerk-custom-ui` - Custom authentication flows with `useSignIn` / `useSignUp` hooks - Appearance and styling (themes, colors, layout) - `<Show>` component for conditional rendering **Advanced Next.js patterns** → Use `clerk-nextjs-patterns` - Server vs Client auth APIs - Middleware strategies - Server Actions, caching - API route protection **React patterns** → Use `clerk-react-patterns` - Hooks (`useAuth`, `useUser`, `useClerk`) - Protected routes, auth guards - Router integration **React Router patterns** → Use `clerk-react-router-patterns` - Loaders & actions with auth - Route protection - SSR auth **Vue patterns** → Use `clerk-vue-patterns` - Composables (`useAuth`, `useUser`, `useClerk`) - Vue Router guards - Pinia auth store integration **Nuxt patterns** → Use `clerk-nuxt-patterns` - Server middleware auth - SSR auth with composables - Server API routes **Astro patterns** → Use `clerk-astro-patterns` - SSR auth pages - Island components with React - Middleware & API routes **TanStack Start patterns** → Use `clerk-tanstack-patterns` - Server functions with auth - Route protection via loaders - Vite plugin and request middleware setup **Expo / React Native auth** → Use `clerk-expo` - Prebuilt native components (AuthView, UserButton) - Custom flows: email, password, SMS/phone OTP, MFA - OAuth/SSO and native Google/Apple sign-in - Expo Router protected routes, token storage, push notifications **Chrome Extension patterns** → Use `clerk-chrome-extension-patterns` - Background scripts auth - Popup auth
Preview of the first 4,000 characters. Read full instructions →
clerk-android8.37 KB
---
name: clerk-android
description: Implement Clerk authentication for native Android apps using Kotlin and
Jetpack Compose with clerk-android source-guided patterns. Use for prebuilt AuthView/UserButton
or custom API-driven auth flows. Do not use for Expo or React Native projects.
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.2.0
compatibility: Requires Android Studio and clerk-android Gradle dependency
---
# Clerk Android (Native)
This skill implements Clerk in native Android projects by following current `clerk-android` SDK and docs patterns.
## Activation Rules
Activate this skill when either condition is true:
- The user explicitly asks for Android, Kotlin, Jetpack Compose, or native mobile Clerk implementation on Android.
- The project appears to be native Android (for example `build.gradle(.kts)` with Android plugins, `AndroidManifest.xml`, `app/src/main/java`, Compose UI files).
Do not activate this skill when either condition is true:
- The project is Expo.
- The project is React Native.
If Expo/React Native signals are present, route to the general setup skill instead.
## What Do You Need?
| Task | Reference |
|------|-----------|
| Prebuilt AuthView / UserButton (fastest) | references/prebuilt.md |
| Custom API-driven auth flows (full control) | references/custom.md |
## Quick Start
| Step | Action |
|------|--------|
| 1 | Confirm project type is native Android and not Expo/React Native |
| 2 | Determine flow type (`prebuilt` or `custom`) and load the matching reference file |
| 3 | Ensure a real Clerk publishable key exists (or ask developer) |
| 4 | Ensure correct Clerk artifacts are installed for the selected flow |
| 5 | Read official Android quickstart and verify required setup (Native API, min SDK/Java, manifest, initialization) |
| 6 | Inspect `clerk-android` source/sample patterns relevant to selected flow |
| 7 | Implement flow by following only the selected reference checklist |
## Decision Tree
```text
User asks for Clerk in Android/Kotlin
|
+-- Expo/React Native project detected?
| |
| +-- YES -> Do not use this skill
| |
| +-- NO -> Continue
|
+-- Existing auth UI detected?
| |
| +-- Prebuilt views detected -> Load references/prebuilt.md
| |
| +-- Custom flow detected -> Load references/custom.md
| |
| +-- New implementation -> Ask developer prebuilt/custom, then load matching reference
|
+-- Ensure publishable key and SDK initialization path
|
+-- Ensure correct Android artifacts are installed
|
+-- Verify quickstart prerequisites in project
|
+-- Implement using selected flow reference
```
## Flow References
After flow type is known, load exactly one:
- Prebuilt flow: [references/prebuilt.md](references/prebuilt.md)
- Custom flow: [references/custom.md](references/custom.md)
Do not blend the two references in a single implementation unless the developer explicitly asks for a hybrid approach.
## Interaction Contract
Before any implementation edits, the agent must have both:
- flow choice: `prebuilt` or `custom`
- a real Clerk publishable key
If either value is missing from the user request/context:
- ask the user for the missing value(s)
- pause and wait for the answer
- do not edit files or install dependencies yet
Only skip asking when the user has already explicitly provided the value in this conversation.
## Source-Driven Templates
Do not hardcode implementation examples in this skill. Inspect current `clerk-android` source/docs for the installed SDK version before implementing.
| Use Case | Source of Truth |
|----------|-----------------|
| SDK artifacts and dependency split (`clerk-android-api` vs `clerk-android-ui`) | `clerk-android` README and Android install docs |
| SDK initialization and publishable key wiring | Android quickstart and `source/api/.../Clerk.kt` |
| Prebuilt auth and profile behavior | `source/Preview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
clerk-astro-patterns3.72 KB
---
name: clerk-astro-patterns
description: 'Astro patterns with Clerk — middleware, SSR pages, island components,
API routes, static vs SSR rendering. Triggers on: astro clerk, clerk astro middleware,
astro protected page, clerk island component, astro API route auth, clerk astro
SSR.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.0.0
---
# Astro Patterns
SDK: `@clerk/astro` v4+. Requires Astro 5+.
## What Do You Need?
| Task | Reference |
|------|-----------|
| Configure middleware (bare `clerkMiddleware()`, checks per page) | references/middleware.md |
| Protect SSR pages | references/ssr-pages.md |
| Use Clerk in island components | references/island-components.md |
| Auth in API routes | references/api-routes.md |
| Use Clerk with React in Astro | references/astro-react.md |
## Mental Model
Astro has two rendering modes per page: **SSR** and **static prerender**. Clerk works differently in each:
- **SSR pages** — use `Astro.locals.auth()` which is populated by the middleware
- **Static pages** (`export const prerender = true`) — Clerk middleware skips them; use client-side hooks in islands
- **Islands** — React/Vue/Svelte components; use `useAuth()` and other hooks from `@clerk/astro/react`
```
Request → clerkMiddleware() → SSR page → Astro.locals.auth()
↓
Island (.client) → useAuth() hook
```
## Setup
### astro.config.mjs
```ts
import { defineConfig } from 'astro/config'
import clerk from '@clerk/astro'
export default defineConfig({
integrations: [clerk()],
output: 'server',
})
```
### src/middleware.ts
```ts
import { clerkMiddleware } from '@clerk/astro/server'
export const onRequest = clerkMiddleware()
```
The middleware populates `Astro.locals.auth()`. Each page and API route checks for itself. `createRouteMatcher` was removed in `@clerk/astro` 4.0 (deprecated in 3.x). Don't add it. Existing uses must move to page and API-route checks before upgrading. See the [Astro `clerkMiddleware()` reference](https://clerk.com/docs/reference/astro/clerk-middleware).
## SSR Page Auth
```astro
---
const { userId, orgId } = Astro.locals.auth()
if (!userId) return Astro.redirect('/sign-in')
---
<h1>Dashboard</h1>
```
## API Route Auth
```ts
// src/pages/api/data.ts
import type { APIRoute } from 'astro'
export const GET: APIRoute = ({ locals }) => {
const { userId } = locals.auth()
if (!userId) return new Response('Unauthorized', { status: 401 })
return Response.json({ userId })
}
```
## Common Pitfalls
| Symptom | Cause | Fix |
|---------|-------|-----|
| `Astro.locals.auth` is undefined | Missing middleware | Add `clerkMiddleware` to `src/middleware.ts` |
| Auth works in dev but not production | `output: 'static'` globally | Set `output: 'server'` or `hybrid` for protected pages |
| Static page has no auth | Prerendered pages skip middleware | Use `export const prerender = false` or move to island |
| Island not reactive to sign-in | Missing `client:load` directive | Add `client:load` to the island component |
## Import Map
| What | Import From |
|------|-------------|
| `clerkMiddleware`, `clerkClient` | `@clerk/astro/server` |
| `useAuth`, `UserButton` (no `useUser`) | `@clerk/astro/react` |
| `$userStore`, `$authStore` | `@clerk/astro/client` |
| Astro components (`<SignIn>`, etc.) | `@clerk/astro/components` |
## Env Variables
```
# .env
PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
```
Astro uses `PUBLIC_` prefix for client-exposed variables (not `NEXT_PUBLIC_`).
## See Also
- `clerk-setup` - Initial Clerk install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations
## Docs
[Astro SDK](https://clerk.com/docs/astro/getting-started/quickstart)
Referenced files: 13 — file references are metadata, not package contents.
clerk-backend-api15.7 KB
---
name: clerk-backend-api
description: "Clerk Backend REST API explorer and executor. Browse tags, inspect endpoint schemas, and execute authenticated requests. Use when listing users, managing organizations, or calling any Clerk API endpoint."
allowed-tools: Bash, Read, Grep, Skill, WebFetch
license: MIT
compatibility: Requires CLERK_SECRET_KEY (sk_*) for Backend API calls.
---
## Options context
User Prompt: $ARGUMENTS
## CRITICAL: Mandatory checks before EVERY write request
Before ANY POST / PATCH / PUT / DELETE, you MUST do ALL of the following in your response:
1. **Check CLERK_SECRET_KEY** — verify it is set:
```bash
echo $CLERK_SECRET_KEY | head -c 10
```
If empty, stop and ask the user. Do not proceed without a valid key.
2. **Check CLERK_BAPI_SCOPES** — run:
```bash
echo $CLERK_BAPI_SCOPES
```
Inspect the output. If scopes are missing or do not include the required write permission, tell the user: *"This is a write operation and your current scopes may not allow it. Rerun with --admin to bypass?"* Do NOT attempt the request and fail — ask first.
3. **For DELETE requests:** warn explicitly that the action is **IRREVERSIBLE** and list exactly what data will be permanently destroyed (user record, all sessions, all memberships, all associated data). Require explicit confirmation before proceeding. This warning is MANDATORY — never skip it.
4. **For metadata operations:** always explain which metadata type is being used and why (see Metadata types section below).
---
## FAST PATH: Common operations (use directly, no spec fetching needed)
For the operations below, skip spec fetching and execute immediately using these exact templates. Substitute `$CLERK_SECRET_KEY`, `$USER_ID`, `$ORG_ID`, `$EMAIL` as needed from the user's context.
### Create organization + invite member (two-step)
```bash
# Step 1 — Create organization
ORG=$(curl -s -X POST "https://api.clerk.com/v1/organizations" \
-H "Authorization: Bearer $CLERK_SECRET_KEY" \
-H "Content-Type: application/json" \
-d "{\"name\": \"Acme Corp\", \"created_by\": \"$USER_ID\"}")
echo "$ORG" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d, indent=2))"
# Step 2 — Extract org ID
ORG_ID=$(echo "$ORG" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
# Step 3 — Invite member with role
curl -s -X POST "https://api.clerk.com/v1/organizations/${ORG_ID}/invitations" \
-H "Authorization: Bearer $CLERK_SECRET_KEY" \
-H "Content-Type: application/json" \
-d "{\"email_address\": \"user@example.com\", \"role\": \"org:admin\"}" \
| python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))"
```
**Roles:** use `"org:admin"` or `"org:member"` (always prefix with `org:`).
### SDK equivalent (for Next.js / TypeScript projects with `@clerk/nextjs` or `@clerk/backend`)
```typescript
import { clerkClient } from '@clerk/nextjs/server'
// OR if using @clerk/backend directly:
// import { createClerkClient } from '@clerk/backend'
// const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })
// Step 1: Create organization
const org = await clerkClient.organizations.createOrganization({
name: 'Acme Corp',
createdBy: userId, // required — the ID of the user creating the org
})
// Step 2: Invite member to the org
const invitation = await clerkClient.organizations.createOrganizationInvitation({
organizationId: org.id,
emailAddress: 'user@example.com',
role: 'org:admin', // or 'org:member'
})
```
### Update user metadata
**Always explain the three metadata types before asking which to use:**
| Type | Field | Readable by | Writable by | Use for |
|------|-------|-------------|-------------|---------|
| Public | `public_metadata` | Client + Server | **Server only** | Plan tier, roles, feature flags the frontend reads |
| Private | `private_metadata` | **Server only** | **Server only** | Stripe IDs, compliance flags, internal identifiers |
| Unsafe |Preview of the first 4,000 characters. Read full instructions →
Referenced files: 5 — file references are metadata, not package contents.
clerk-billing20.7 KB
---
name: clerk-billing
description: Clerk Billing for subscription management - render Clerk's PricingTable
and in-app checkout drawer, configure subscription plans, seat-limit plans for
B2B, feature entitlements with has(), and billing webhooks. Use for SaaS
monetization, plan gating, checkout flows, trials, invoicing, and subscription
lifecycle management.
allowed-tools: WebFetch
license: MIT
compatibility: Requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY, and CLERK_WEBHOOK_SIGNING_SECRET. Billing must be enabled in Clerk Dashboard → Billing. Development instances can use the shared Clerk development gateway; production instances require a Stripe account for payment processing.
metadata:
author: clerk
version: 1.1.0
---
# Billing
> **STOP, prerequisite.** Billing must be enabled before any `<PricingTable />`, `<CheckoutButton />`, `has({ plan })`, or `has({ feature })` usage works. Two paths: (1) [Dashboard → Billing → Settings](https://dashboard.clerk.com/last-active?path=billing/settings), or (2) `clerk enable billing` (see "Agent-first: Programmatic billing config" below). Enabling auto-creates default `free_user` / `free_org` plans. Dev instances can use the shared Clerk development gateway (no Stripe account needed); production requires a Stripe account for payment processing only.
>
> **Note**: Billing APIs are still experimental. Pin your `@clerk/nextjs` and `clerk-js` package versions. See `clerk` skill for the supported version table.
## Quick Start
1. **Enable Billing**, via [Dashboard → Billing → Settings](https://dashboard.clerk.com/last-active?path=billing/settings) or `clerk enable billing` (see Agent-first section). Skipping this throws `cannot_render_billing_disabled` in dev and renders empty in prod.
2. **Create plans in the matching tab**, [Dashboard → Billing → Plans](https://dashboard.clerk.com/last-active?path=billing/plans). Two tabs, slugs scoped per tab, not movable after creation:
- **User Plans** → `<PricingTable />` (default `for="user"`)
- **Organization Plans** → `<PricingTable for="organization" />`
Wrong-tab is the #1 cause of an empty `<PricingTable />`. Plans live in Clerk; not synced to Stripe.
3. **Add features inside a plan**, open the plan in Dashboard → Billing → Plans, use its Features section. Features are scoped per plan, not global. The same slug can attach to multiple plans; `has({ feature: 'export' })` matches if the active plan contains that slug.
4. **Render `<PricingTable />`** (pass `for="organization"` for B2B).
5. **Gate access** with `has({ plan })` or `has({ feature })` from `auth()`.
6. **Handle billing webhooks** for subscription lifecycle.
## Dashboard shortcuts
| Action | URL |
|---|---|
| Enable Billing | `https://dashboard.clerk.com/last-active?path=billing/settings` |
| Create / edit plans | `https://dashboard.clerk.com/last-active?path=billing/plans` |
| Membership mode (B2C + B2B coexistence) | `https://dashboard.clerk.com/last-active?path=organizations-settings` |
| Edit features | Plans → click a plan → Features section (no direct URL) |
## Agent-first: Programmatic billing config
The full billing config (enable toggles, plans, features, plan-feature attachments) is editable via PLAPI without touching the Dashboard. Useful for agents seeding plans, replicating config across instances, or version-controlling billing structure.
Pre-req: project linked to the Clerk app (`clerk auth login` + `clerk link`, see `clerk-cli`). Billing is account-only — unlike orgs, it cannot be enabled on an unclaimed app; claim the app first.
### Enable Billing via CLI
```bash
clerk enable billing # both targets (default, auto-creates free_user + free_org plans)
clerk enable billing --for org # org only
clerk enable billing --for user # user only
```
### Pull current billing config
```bash
clerk config pull --keys billing > billing.json
```
This writes the current billing config (toggles + plans + features) for thePreview of the first 4,000 characters. Read full instructions →
Referenced files: 5 — file references are metadata, not package contents.
clerk-chrome-extension-patterns11.4 KB
---
name: clerk-chrome-extension-patterns
description: 'Chrome Extension auth with @clerk/chrome-extension -- popup/sidepanel
setup, syncHost for OAuth/SAML via web app, createClerkClient for service workers
and headless extensions, stable CRX ID. Triggers on: Chrome extension auth, Plasmo
clerk, popup sign-in, syncHost, background service worker token, createClerkClient,
headless extension.'
license: MIT
allowed-tools: WebFetch
compatibility: Requires PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY (Plasmo prefix for public env vars) and CLERK_FRONTEND_API.
metadata:
author: clerk
version: 2.0.0
references:
- references/sync-host.md
- references/create-clerk-client.md
- references/content-scripts.md
- references/headless-extension.md
---
# Chrome Extension Patterns
## CRITICAL RULES
1. OAuth (Google, GitHub, etc.) and SAML are NOT supported in popups or side panels -- use `syncHost` to delegate auth to your web app
2. Email links (magic links) don't work in popups -- the popup closes when the user clicks outside, resetting sign-in state
3. Side panels don't auto-refresh auth state -- users must close and reopen the side panel after signing in via the web app
4. Service workers and content scripts have NO access to Clerk React hooks -- use `createClerkClient()` or message passing
5. Extension URLs use `chrome-extension://` not `http://` -- all redirect URLs must use `chrome.runtime.getURL('.')`
6. Without a stable CRX ID, every rebuild breaks auth -- configure `key` in manifest BEFORE deploying
7. Content scripts cannot use Clerk directly due to origin restrictions -- Clerk enforces strict allowed origins
8. Bot protection must be DISABLED in Clerk Dashboard -- Cloudflare bot detection is not supported in extension environments
## Authentication Options
| Method | Popup | Side Panel | syncHost (with web app) |
|--------|-------|------------|------------------------|
| Email + OTP | Yes | Yes | Yes |
| Email + Link | No | No | Yes |
| Email + Password | Yes | Yes | Yes |
| Username + Password | Yes | Yes | Yes |
| SMS + OTP | Yes | Yes | Yes |
| OAuth (Google, GitHub, etc.) | **NO** | **NO** | **YES** |
| SAML | **NO** | **NO** | **YES** |
| Passkeys | Yes | Yes | Yes |
| Google One Tap | No | No | Yes |
| Web3 | No | No | Yes |
## Quick Start (Plasmo)
```bash
npx create-plasmo --with-tailwindcss --with-src my-extension
cd my-extension
npm install @clerk/chrome-extension
```
Enable **Native API** in Clerk Dashboard under Native applications. Required for all extension integrations.
`.env.development`:
```
PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_FRONTEND_API=https://your-app.clerk.accounts.dev
```
`src/popup.tsx`:
```tsx
import { ClerkProvider, Show, SignInButton, SignUpButton, UserButton } from '@clerk/chrome-extension'
const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY
const EXTENSION_URL = chrome.runtime.getURL('.')
if (!PUBLISHABLE_KEY) {
throw new Error('Missing PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY')
}
function IndexPopup() {
return (
<ClerkProvider
publishableKey={PUBLISHABLE_KEY}
afterSignOutUrl={`${EXTENSION_URL}/popup.html`}
signInFallbackRedirectUrl={`${EXTENSION_URL}/popup.html`}
signUpFallbackRedirectUrl={`${EXTENSION_URL}/popup.html`}
>
<Show when="signed-out">
<SignInButton mode="modal" />
<SignUpButton mode="modal" />
</Show>
<Show when="signed-in">
<UserButton />
</Show>
</ClerkProvider>
)
}
export default IndexPopup
```
Use `mode="modal"` for `SignInButton` -- navigating to a separate page breaks the popup flow.
## syncHost -- Sync Auth with Web App
Use this when you need OAuth, SAML, or want the extension to reflect sign-in from your web app.
**How it works**: The extension reads the Clerk session cookie from your web app's domain via `host_permissions`.
**Step 1 -- Environment variables:**
`.env.development`:
```
PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_..Preview of the first 4,000 characters. Read full instructions →
Referenced files: 8 — file references are metadata, not package contents.
clerk-cli38 KB
--- name: clerk-cli description: >- Operate the Clerk CLI (`clerk` binary) for authentication, user/org/session management, impersonation, local webhook testing, deploy verification, instance config, env keys, feature toggles, and any Clerk Backend, Platform, or Frontend API call. Use when the user mentions Clerk management tasks, "list clerk users", "impersonate a user", "test webhooks locally", "enable orgs", "enable billing", "clerk env pull", "clerk doctor", "clerk deploy", "clerk api", or any ad-hoc Clerk API request. Prefer the CLI over raw HTTP: it handles auth, key resolution, app/instance targeting, and formatting automatically. license: MIT --- # Clerk CLI The `clerk` binary is a pre-authenticated gateway to Clerk's Backend API and Platform API, plus project-level tooling (auth, linking, env pulls, instance config). When the user asks anything that touches a Clerk resource, reach for `clerk` first instead of hand-rolling `curl`. For setup or `init` requests, use the [`clerk-setup`](../clerk-setup/SKILL.md) skill as the source of truth. Its package-runner, accountless, migration, and init-first guidance takes precedence over the general operational prerequisites below. > This skill targets clerk `latest`. If `clerk --version` disagrees with the latest available CLI, refresh it with `clerk update`, or invoke the latest through a package runner such as `bunx clerk@latest`. The binary is always the source of truth, so run `clerk <command> --help` to verify anything this skill claims. ## Execution environment (prefer the host, understand the sandbox warning) Most AI coding agents default to running shell commands in a sandbox where the user's home directory, OS keychain, browser launch, localhost callback binding, or network access may be blocked. The Clerk CLI depends on all of those host capabilities: - **OS credential store**: `clerk auth login` stores the OAuth token in the system keychain. A sandbox without keychain access reports "not logged in" even when the host is authenticated. - **Home-directory Clerk state**: saved config, cached metadata, and fallback credentials live under the user's Clerk config/data directories. - **Linked project metadata**: resolved from the repo's git remote plus Clerk config. Sandboxes with stripped repo state or blocked home-dir reads can misreport "not linked". - **Local `.env*` files**: publishable and secret keys materialized by `clerk env pull`. - **Outbound network access to Clerk**: every Backend and Platform API call. - **Browser + localhost OAuth callback**: `clerk auth login` needs both. In agent mode, the CLI now does a **best-effort warn-once check** at the host-sensitive library boundaries. When it detects that host-only Clerk state or system capabilities are unavailable, it emits: ```text Host-only Clerk state or system capabilities may be unavailable in agent mode. This may be a sandboxed run. Re-run this command on the host shell before trusting auth, link, env, or API failures. ``` Treat that warning as authoritative. The command may continue, but any auth, link, env, config, API, browser, or OAuth callback failure from that invocation is untrusted until you rerun the same command on the host. **Prefer these commands on the user's host shell, not in a sandbox:** `clerk doctor`, `clerk whoami`, `clerk auth login`, `clerk link`, `clerk env pull`, `clerk apps ...`, `clerk config ...`, `clerk api ...`. If a command was accidentally run in a sandbox and it reports `Not logged in`, `auth_required`, `not linked`, missing env, keychain/file permission errors, or network failures, **do not treat the result as authoritative**. Rerun it on the host before acting on it or reporting it to the user. ## Invoking the CLI Before running any `clerk` command, figure out which binary to invoke and bind that choice for the rest of the session: ```sh # 1. Prefer a globally installed binary when it matches the skill's target version. command -v c
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 3 — file references are metadata, not package contents.
clerk-custom-ui6.34 KB
---
name: clerk-custom-ui
description: Custom authentication flows and component appearance - hooks (useSignIn,
useSignUp), themes, colors, fonts, CSS. Use for custom sign-in/sign-up flows, appearance
styling, visual customization, branding.
allowed-tools: WebFetch
license: MIT
metadata:
author: clerk
version: 2.3.0
---
# Custom UI
> **Prerequisite**: Ensure `ClerkProvider` wraps your app. See `clerk-setup` skill.
>
> **Version**: Check `package.json` for the SDK version — see `clerk` skill for the version table. This determines which custom flow references to use below.
This skill covers two areas:
1. **Custom authentication flows** — build your own sign-in/sign-up UI with hooks
2. **Appearance customization** — theme, style, and brand Clerk's pre-built components
## What Do You Need?
| Task | Reference |
|------|-----------|
| Custom sign-in (Core 2 / LTS) | core-2/custom-sign-in.md |
| Custom sign-up (Core 2 / LTS) | core-2/custom-sign-up.md |
| Custom sign-in (Current SDK v7+) | core-3/custom-sign-in.md |
| Custom sign-up (Current SDK v7+) | core-3/custom-sign-up.md |
| Show component pattern (Current SDK) | core-3/show-component.md |
## Custom Flow References
| Task | Core 2 | Current |
|------|--------|---------|
| Custom sign-in (useSignIn) | `core-2/custom-sign-in.md` | `core-3/custom-sign-in.md` |
| Custom sign-up (useSignUp) | `core-2/custom-sign-up.md` | `core-3/custom-sign-up.md` |
| `<Show>` component | *(use `<SignedIn>`, `<SignedOut>`, `<Protect>`)* | `core-3/show-component.md` |
---
## Appearance Customization
Appearance customization applies to both Core 2 and the current SDK.
### Component Customization Options
| Task | Documentation |
|------|---------------|
| Appearance prop overview | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/overview |
| Options (structure, logo, buttons) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/options |
| Themes (pre-built dark/light) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/themes |
| Variables (colors, fonts, spacing) | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/variables |
| CAPTCHA configuration | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/captcha |
| Bring your own CSS | https://clerk.com/docs/nextjs/guides/customizing-clerk/appearance-prop/bring-your-own-css |
### Appearance Pattern
```typescript
<SignIn
appearance={{
variables: {
colorPrimary: '#0000ff',
borderRadius: '0.5rem',
},
options: {
logoImageUrl: '/logo.png',
socialButtonsVariant: 'iconButton',
},
}}
/>
```
> **Core 2 ONLY (skip if current SDK):** The `options` property was named `layout`. Use `layout: { logoImageUrl: '...', socialButtonsVariant: '...' }` instead of `options`.
### variables (colors, typography, borders)
| Property | Description |
|----------|-------------|
| `colorPrimary` | Primary color throughout |
| `colorBackground` | Background color |
| `borderRadius` | Border radius (default: `0.375rem`) |
**Opacity change:** `colorRing` and `colorModalBackdrop` now render at full opacity. Use explicit `rgba()` values if you need transparency.
> **Core 2 ONLY (skip if current SDK):** `colorRing` and `colorModalBackdrop` rendered at 15% opacity by default.
### options (structure, logo, social buttons)
| Property | Description |
|----------|-------------|
| `logoImageUrl` | URL to custom logo |
| `socialButtonsVariant` | `'blockButton'` \| `'iconButton'` \| `'auto'` |
| `socialButtonsPlacement` | `'top'` \| `'bottom'` |
| `showOptionalFields` | Show optional fields (default: `false`) |
> **Core 2 ONLY (skip if current SDK):** This property is called `layout`, not `options`. Also, `showOptionalFields` defaulted to `true`.
### Themes
Install themes from `@clerk/ui`:
```bash
npm install @clerk/ui
```
```typescript
import { dark } from '@clerk/ui/themes'
<ClerkProvider appearance={{ theme: darkPreview of the first 4,000 characters. Read full instructions →
Referenced files: 5 — file references are metadata, not package contents.
clerk-expo11 KB
--- name: clerk-expo description: Add Clerk authentication to Expo and React Native apps using @clerk/expo. Use for Expo setup, prebuilt native components (AuthView, UserButton), custom sign-in/sign-up flows (email, password, SMS/phone OTP, MFA), OAuth/SSO, native Google/Apple sign-in, Expo Router protected routes, biometrics, and push notifications. Do not use for native Swift/iOS, native Android/Kotlin, or web-only framework projects. license: MIT allowed-tools: WebFetch metadata: author: clerk version: 2.0.0 compatibility: Requires @clerk/expo v3.4+ (written against v3.6.x, July 2026). Expo SDK 53-56, React Native 0.75+. --- # Clerk Expo (React Native) Implement Clerk in Expo / React Native projects. This skill inlines verified patterns for the stable surface (provider, token cache, flows) and requires source inspection of the installed `@clerk/expo` package for anything volatile (component props, hook signatures). ## Activation Rules Activate when either is true: - The user asks for auth in an Expo or React Native app, or mentions `@clerk/expo`, `ClerkProvider`, Expo Router auth, or Clerk hooks in a native app. - The project is Expo/React Native (`app.json` / `app.config.js`, `expo` in `package.json`, `metro.config.js`, `@clerk/expo` dependency). Route away when: - Native iOS/Swift project (`.xcodeproj`, `Package.swift`) → `clerk-swift` - Native Android/Kotlin project (`build.gradle` without React Native) → `clerk-android` - Web-only framework (Next.js, Remix, plain React, etc.) → the matching framework skill ## Intent Map Match what the user asked for, then load the reference(s) listed. Load only what the task needs. | User intent (examples) | Path | Reference | |------------------------|------|-----------| | "Add auth to my app" / "add sign-in with Clerk" | Prebuilt native components (default) | references/setup.md + references/prebuilt-components.md | | "Add auth" but Expo Go / web / custom UI required | Custom flows | references/setup.md + references/custom-flows.md | | "Add phone / SMS auth", "email OTP", "passwordless" | Custom flow, `phoneCode` / `emailCode` | references/custom-flows.md | | "Sign in with Google/Apple/GitHub", "social login", "SSO" | Browser SSO or native buttons | references/sso-and-native-auth.md | | "MFA / 2FA / TOTP", "forgot password", "email link" | Custom flow additions | references/custom-flows.md | | "Protect routes/screens", "redirect if signed out" | Expo Router guards | references/protected-routes.md | | "Show user profile", "org switching", "push notifications", "sign out", "call my backend" | App recipes | references/recipes.md | | "Biometric login", "Face ID", "passkeys" | Device features | references/recipes.md | ## Default Path Decision When the user says "add auth" without specifying UI: 1. **Default to prebuilt native components** (`AuthView` + `UserButton` from `@clerk/expo/native`). Fastest to working auth; UI is maintained by Clerk. Tell the developer they are in beta and require a development build. 2. **Fall back to custom flows** when any of these hold — say why when you switch: - The project must run in Expo Go (no dev build). - The app targets web (native components don't render on web). - The developer wants their own UI or a specific brand experience beyond theming. 3. If the developer has an existing auth UI, extend what's there — don't rip out custom flows to insert `AuthView` (or vice versa) without being asked. Do not blend prebuilt components and custom flows for the same auth step (e.g. `AuthView` plus a custom password form). Blending is allowed only when the developer explicitly asks. ## Quick Workflow 1. Confirm project type (Expo/RN) and pick the path per the Intent Map / Default Path rules. 2. Follow references/setup.md: install, env key, provider, token cache, config plugin, build type. 3. Verify dashboard prerequisites (Gate 2 and Gate 3 below). 4. Implement from the selected reference only. 5. Verify by building, not just b
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 7 — file references are metadata, not package contents.
clerk-mcp1.81 KB
--- name: clerk-mcp description: Use for Clerk SDK guidance or to manage applications, users, organizations, domains, billing, and instance configuration in a connected Clerk workspace through the Clerk MCP server. --- # Clerk MCP Use the bundled `clerk` MCP server for Clerk implementation guidance and connected workspace operations. Check the available tool list because authenticated tools depend on the connection and granted scopes. For implementation guidance, use the public tools for: - Adding Clerk authentication to a frontend or backend app. - Choosing or applying Clerk SDK hooks, helpers, or components. - Implementing B2B SaaS organization flows, organization switching, role checks, or billing patterns. - Looking up Clerk quickstarts for Next.js App Router, React/Vite, Expo, Astro, Remix, Express, or Go. Prefer MCP-provided snippets and quickstarts over guessing API shapes from memory. Start with `list_clerk_sdk_snippets` when the right slug is unclear, then call `clerk_sdk_snippet` for the specific snippet or bundle. For workspace operations, use `whoami` to identify the connected account, active workspace, and granted scopes. When available, use the authenticated tools to inspect applications, users, organizations, domains, OAuth providers, and instance configuration, or to apply the requested application, user, and configuration changes. Check the target application and instance before a write. Use a tool's `dry_run` option to preview supported changes, and require the tool's explicit confirmation parameter for irreversible operations. Authentication and scope upgrades happen through the MCP connection. If a tool is unavailable or a scope is denied, explain the missing access instead of assuming it was granted. Never include secret keys, tokens, or end-user personal data in `submit_feedback` reports.
clerk-nextjs-patterns11.7 KB
---
name: clerk-nextjs-patterns
description: Advanced Next.js patterns - middleware, Server Actions, caching with
Clerk.
license: MIT
allowed-tools: WebFetch
compatibility: Requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY. For manual JWT verification (standalone API servers without Clerk middleware), additionally requires CLERK_JWT_KEY or CLERK_PEM_PUBLIC_KEY.
metadata:
author: clerk
version: 2.2.0
---
# Next.js Patterns
> **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.
For basic setup, see `clerk-setup` skill.
> **Route protection:** call `await auth.protect()` in each page, Route Handler, and Server Function. Keep `clerkMiddleware()` bare. `createRouteMatcher` is deprecated in `@clerk/nextjs` 7 and will be removed in the next major version. Don't add it. If a project already uses it, leave it working and point the user to the [migration guide](https://clerk.com/docs/guides/development/upgrading/upgrade-guides/migrate-from-create-route-matcher).
## What Do You Need?
| Task | Reference |
|------|-----------|
| Server vs client auth (`auth()` vs hooks) | references/server-vs-client.md |
| Protect routes (check in each page, handler, and Server Function) | references/middleware-strategies.md |
| Protect Server Actions | references/server-actions.md |
| API route auth (401 vs 403) | references/api-routes.md |
| Cache auth data (user-scoped caching) | references/caching-auth.md |
| Fix `next build` errors under Cache Components | [Cache Components](#cache-components) |
## References
| Reference | Description |
|-----------|-------------|
| `references/server-vs-client.md` | `await auth()` vs hooks |
| `references/middleware-strategies.md` | `auth.protect()` in each resource, bare `clerkMiddleware()` in `proxy.ts` (Next.js <=15: `middleware.ts`) |
| `references/server-actions.md` | Protect mutations |
| `references/api-routes.md` | 401 vs 403 |
| `references/caching-auth.md` | User-scoped caching with `'use cache'` |
## Mental Model
Server vs Client = different auth APIs:
- **Server**: `await auth()` from `@clerk/nextjs/server` (async!)
- **Client**: `useAuth()` hook from `@clerk/nextjs` (sync)
Never mix them. Server Components use server imports, Client Components use hooks.
Key properties from `auth()`:
- `isAuthenticated` — boolean, replaces the `!!userId` pattern
- `sessionStatus` — `'active'` | `'pending'`, for detecting incomplete session tasks
- `userId`, `orgId`, `orgSlug`, `has()`, `protect()` — unchanged
> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` and `sessionStatus` are not available. Check `!!userId` instead.
## Minimal Pattern
```tsx
// Server Component
import { auth } from '@clerk/nextjs/server'
import { Suspense } from 'react'
async function Greeting() {
const { isAuthenticated, userId } = await auth() // MUST await!
if (!isAuthenticated) return <p>Not signed in</p>
return <p>Hello {userId}</p>
}
export default function Page() {
return (
<Suspense>
<Greeting />
</Suspense>
)
}
```
`auth()` reads the request, so it runs in an async child inside `<Suspense>`, not in the page itself. See [Cache Components](#cache-components).
> **Core 2 ONLY (skip if current SDK):** `isAuthenticated` is not available. Use `if (!userId)` instead.
### Conditional Rendering with `<Show>`
`<Show>` renders its children based on auth state. It covers both authentication checks and authorization (feature, plan, role, permission) in one component. In a Server Component, it reads the session from the request on the server, so wrap it in `<Suspense>`. In a Client Component, it reads client-side auth state and needs no boundary.
**Authentication check:**
```tsx
import { Show } from '@clerk/nextjs'
import { Suspense } from 'react'
<Suspense>
<Show when="signed-in" fallback={<p>Please sign in</p>}>
<Dashboard />
</ShoPreview of the first 4,000 characters. Read full instructions →
Referenced files: 12 — file references are metadata, not package contents.
clerk-nuxt-patterns3.1 KB
---
name: clerk-nuxt-patterns
description: 'Nuxt 3 auth patterns with @clerk/nuxt - middleware, composables, server
API routes, SSR. Triggers on: Nuxt auth, useAuth composable, clerkMiddleware Nuxt,
server API Clerk, Nuxt route protection.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.0.0
---
# Nuxt Patterns
## What Do You Need?
| Task | Reference |
|------|-----------|
| Protect routes with middleware | references/nuxt-middleware.md |
| Auth in server API routes (Nitro) | references/server-api-routes.md |
| useAuth / useUser in components | references/composables.md |
| SSR-safe auth patterns | references/ssr-auth.md |
## References
| Reference | Description |
|-----------|-------------|
| `references/nuxt-middleware.md` | Route protection, clerkMiddleware() |
| `references/server-api-routes.md` | Nitro server route auth |
| `references/composables.md` | useAuth, useUser, useClerk |
| `references/ssr-auth.md` | SSR hydration, server vs client |
## Setup
```
npm install @clerk/nuxt
```
`.env`:
```
NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
NUXT_CLERK_SECRET_KEY=sk_...
```
`nuxt.config.ts`:
```typescript
export default defineNuxtConfig({
modules: ['@clerk/nuxt'],
})
```
This single line auto-configures middleware, plugins, and component auto-imports.
## Mental Model
`@clerk/nuxt` auto-imports all Clerk components and composables — no explicit imports needed in `<script setup>`.
- **Composables** (`useAuth`, `useUser`) — client-side reactive, inside `<script setup>`
- **Server routes** (`clerkClient`) — Nitro server routes, `event.context.auth`
- **Middleware** (`clerkMiddleware`) — auto-registered, use `auth().protect()` to lock routes
## Minimal Pattern
```vue
<!-- pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({ middleware: 'auth' })
const { userId } = useAuth()
</script>
<template>
<Show when="signed-in">
<p>Hello {{ userId }}</p>
</Show>
</template>
```
> `definePageMeta({ middleware: 'auth' })` uses the built-in auth middleware from `@clerk/nuxt`.
## Common Pitfalls
| Symptom | Cause | Fix |
|---------|-------|-----|
| Composables return `undefined` on server | useAuth is client-only | Use `event.context.auth` in server routes |
| Route not protected | Missing `middleware: 'auth'` meta | Add `definePageMeta({ middleware: 'auth' })` |
| `clerkClient` not available | Wrong import path | Import from `@clerk/nuxt/server` |
| Hydration mismatch | Rendering auth state before mounted | Wrap in `<ClientOnly>` or check `isLoaded` |
| Env vars not picked up | Wrong prefix | Nuxt requires `NUXT_PUBLIC_` for public, `NUXT_` for server |
## Org-Aware Pattern
```vue
<script setup lang="ts">
const { orgId, orgRole } = useAuth()
</script>
<template>
<div v-if="orgId">
<p>Org: {{ orgId }}</p>
<p v-if="orgRole === 'org:admin'">Admin panel</p>
</div>
<div v-else>
<OrganizationSwitcher />
</div>
</template>
```
## See Also
- `clerk-setup` - Initial Clerk install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations
## Docs
[Nuxt SDK](https://clerk.com/docs/nuxt/getting-started/quickstart)
Referenced files: 8 — file references are metadata, not package contents.
clerk-orgs22.6 KB
--- name: clerk-orgs description: Clerk Organizations for B2B and multi-tenant apps - org switching, roles and permissions, verified domains, and enterprise SSO. Use for team workspaces, RBAC, org-scoped routing, member management. Also load this when a project treats teams, workspaces, tenants, or companies as its customers - shared accounts, inviting teammates, per-seat pricing, per-company data isolation - even when the words "organization" or "B2B" are never used. allowed-tools: WebFetch license: MIT compatibility: Requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY. Organizations must be enabled in Clerk Dashboard → Organizations. Membership mode (required vs optional) must match the B2B vs B2C + B2B coexistence story of your app. metadata: author: clerk version: 3.1.1 --- # Organizations (B2B SaaS) > **STOP — prerequisite.** Organizations must be enabled before any org-related API, hook, or component works. Two paths: (1) [Dashboard → Organizations settings](https://dashboard.clerk.com/last-active?path=organizations-settings), or (2) `clerk enable orgs` (see "Agent-first: Programmatic org management" below). Pick the Membership mode deliberately: `Membership required` (default since 2025-08-22) routes signed-in users through the `choose-organization` task and disables personal accounts, while `Membership optional` keeps personal accounts available for B2C + B2B coexistence. Pick `optional` if you need personal subscriptions alongside org subscriptions. > > **Version**: This skill targets current SDKs (`@clerk/nextjs` v7+, `@clerk/react` v6+ — Core 3). Core 2 differences are noted inline with `> **Core 2 ONLY (skip if current SDK):**` callouts — see `clerk` skill for the full version table. ## Should this app use Organizations? Decide before enabling anything. Read the project, count the signals, then **ask the developer** - do not enable Organizations silently. **Signals this app is multi-tenant** (recommend Organizations): - A model that groups users: `Team`, `Workspace`, `Tenant`, `Company`, `Account` - The same foreign key on most tables: `workspace_id`, `team_id`, `account_id` - Routes scoped to a tenant: `/[workspace]`, `/[slug]/settings`, `/t/:tenantId` - "Invite your team", "members", "seats", or "admin" in UI copy or the README - A `*_members` join table, or hand-rolled `role` / `permission` columns - Per-seat or per-company pricing **Weaker signals** - enough to raise the question, not to answer it: - Sharing or collaboration between individual users: a `Share`, `Collaborator`, or `SharedWith` table keyed on two user IDs - A `role` or `permission` column with no tenant to scope it to - "Collaborators", "shared with you", "invite a friend" in copy **Signals this app is single-user** (do not recommend): - Every table hangs off `user_id` with no container above it, and nothing is shared - No invitation, membership, or sharing concept anywhere - Pricing is per person, or there is none **How to act:** | What you found | What to do | |---|---| | 2 or more strong signals | Recommend Organizations and name the signals you saw. New app: `clerk init --template b2b-saas`. Existing app: `clerk enable orgs`. | | 1 strong signal, or any weaker signal | Raise it as an option, state the tradeoff, let the developer choose. Sharing between individual users is not multi-tenancy - a `Share` table pointing at two user IDs has no tenant - but it is often where a product grows one. | | Nothing above | Don't bring it up. | **Never enable Organizations without asking.** Enabling it also turns on `Membership required`, which routes every signed-in user through organization selection and disables personal accounts. That is wrong for any app that also serves individuals. If the app needs both, it wants `Membership optional`. ## Quick Start 1. **Enable Organizations** — via [Dashboard → Organizations settings](https://dashboard.clerk.com/last-active?path=organizations-settings) or `clerk enable orgs`
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 5 — file references are metadata, not package contents.
clerk-react-patterns4.06 KB
---
name: clerk-react-patterns
description: 'React SPA auth patterns with @clerk/react for Vite/CRA - ClerkProvider
setup, useAuth/useUser/useClerk hooks, React Router protected routes, custom sign-in
flows. Triggers on: Vite Clerk setup, React Router auth, useAuth hook, protected
route, custom sign-in form React.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.0.0
---
# React SPA Patterns
> This skill covers `@clerk/react` for Vite/CRA SPAs. For Next.js use `clerk-nextjs-patterns`. For TanStack Start use `clerk-tanstack-patterns`.
## What Do You Need?
| Task | Reference |
|------|-----------|
| useAuth / useUser / useClerk hooks | references/hooks.md |
| Protected routes with React Router | references/protected-routes.md |
| Custom sign-in / sign-up forms | references/custom-flows.md |
| React Router v6/v7 integration | references/router-integration.md |
## References
| Reference | Description |
|-----------|-------------|
| `references/hooks.md` | useAuth, isLoaded guard |
| `references/protected-routes.md` | ProtectedRoute pattern |
| `references/custom-flows.md` | useSignIn, useSignUp flows |
| `references/router-integration.md` | React Router v6/v7 setup |
## Setup
```
npm install @clerk/react
```
`.env`:
```
VITE_CLERK_PUBLISHABLE_KEY=pk_...
```
`src/main.tsx`:
```tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ClerkProvider } from '@clerk/react'
import App from './App.tsx'
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
<App />
</ClerkProvider>
</StrictMode>,
)
```
## Mental Model
`@clerk/react` is client-only — there is no server-side `auth()`. All auth state comes from hooks.
- `isLoaded` must be `true` before trusting `isSignedIn` — always guard on `isLoaded`
- `useClerk()` gives access to `signOut`, `openSignIn`, `openUserProfile` and other methods
- `getToken()` from `useAuth()` fetches the session JWT for API calls
## Minimal Pattern
```tsx
import { useAuth } from '@clerk/react'
export function Dashboard() {
const { isLoaded, isSignedIn, userId } = useAuth()
if (!isLoaded) return <div>Loading...</div>
if (!isSignedIn) return <div>Please sign in</div>
return <div>Hello {userId}</div>
}
```
## Protected Route (React Router v6/v7)
```tsx
import { Navigate, Outlet } from 'react-router-dom'
import { useAuth } from '@clerk/react'
export function ProtectedRoute() {
const { isLoaded, isSignedIn } = useAuth()
if (!isLoaded) return <div>Loading...</div>
if (!isSignedIn) return <Navigate to="/sign-in" replace />
return <Outlet />
}
```
```tsx
<Routes>
<Route element={<ProtectedRoute />}>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Route>
<Route path="/sign-in" element={<SignIn />} />
</Routes>
```
## Token for API Calls
```tsx
import { useAuth } from '@clerk/react'
export function DataFetcher() {
const { getToken } = useAuth()
async function fetchData() {
const token = await getToken()
if (!token) return
const res = await fetch('/api/data', {
headers: { Authorization: `Bearer ${token}` },
})
return res.json()
}
return <button onClick={fetchData}>Load</button>
}
```
## Common Pitfalls
| Symptom | Cause | Fix |
|---------|-------|-----|
| `isSignedIn` is `undefined` | `isLoaded` is still `false` | Always check `isLoaded` first |
| `ClerkProvider` missing | Provider not at root | Wrap `<App>` in `main.tsx` |
| Env var undefined | Wrong Vite prefix | Use `VITE_CLERK_PUBLISHABLE_KEY`, access via `import.meta.env` |
| Token is `null` | User not signed in | Null-check `getToken()` result |
| Sign-in component shows blank | No `publishableKey` on provider | Pass `publishableKey` explicitly |
## See Also
- `clerk-setup` - Initial Clerk install
- `cPreview of the first 4,000 characters. Read full instructions →
Referenced files: 11 — file references are metadata, not package contents.
clerk-react-router-patterns7.22 KB
---
name: clerk-react-router-patterns
description: 'React Router v7/v8 patterns with Clerk — rootAuthLoader, getAuth in loaders,
clerkMiddleware, protected routes, SSR user data, org switching. Triggers on: react-router
auth, rootAuthLoader, getAuth loader, react-router protected route, loader authentication,
SSR auth react-router, useNavigate may be used only in the context of a Router.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.1.0
---
# React Router Patterns
SDK: `@clerk/react-router` v3.5+. Supports React Router v7.9+ and v8.
## What Do You Need?
| Task | Reference |
|------|-----------|
| Auth in loaders and actions | references/loaders-actions.md |
| Protected routes and redirects | references/protected-routes.md |
| SSR user data and session | references/ssr-auth.md |
## React Router v7 vs v8
Check the installed `react-router` major version before scaffolding — the config differs:
| | v7.9+ | v8+ |
|--|--|--|
| Middleware API | Opt-in: set `future: { v8_middleware: true }` in `react-router.config.ts` | Always on — do NOT set the flag (v8 removed it) |
| `ssr.noExternal` workaround (below) | Not needed | **Required** |
## Minimal Setup
### 1. vite.config.ts (v8 only — REQUIRED)
React Router v8 ships development/production conditional exports. In `react-router dev`,
Vite externalizes `@clerk/react-router` for SSR, so Node resolves the production build of
react-router while the app code gets the development build — two module instances, two
Router contexts. Every request then fails during SSR with:
```
Error: useNavigate() may be used only in the context of a <Router> component.
```
**`npm ls react-router` shows a single copy — that does NOT rule this out.** The
duplication is per export condition, not per installed copy. Do not chase duplicate
installs; add the workaround (upstream issue:
https://github.com/remix-run/react-router/issues/15232):
```ts
import { reactRouter } from '@react-router/dev/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [reactRouter()],
ssr: {
noExternal: ['@clerk/react-router'],
},
})
```
### 2. root.tsx
```tsx
import { Outlet } from 'react-router'
import { rootAuthLoader, clerkMiddleware } from '@clerk/react-router/server'
import { ClerkProvider } from '@clerk/react-router'
import type { Route } from './+types/root'
export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]
export async function loader(args: Route.LoaderArgs) {
return rootAuthLoader(args)
}
export default function App({ loaderData }: Route.ComponentProps) {
return (
<ClerkProvider loaderData={loaderData}>
<Outlet />
</ClerkProvider>
)
}
```
There is no `ClerkApp` HOC in `@clerk/react-router` (that was the `@clerk/remix` API).
Render `<ClerkProvider loaderData={loaderData}>` inside the default export and pass it
the root route's `loaderData`.
### 3. react-router.config.ts (v7 only)
```ts
import type { Config } from '@react-router/dev/config'
export default {
future: {
v8_middleware: true,
},
} satisfies Config
```
On v8, omit the `future` block entirely — the flag no longer exists.
> **Required**: `rootAuthLoader` must be called in `root.tsx`'s loader. Without it, `getAuth` throws in nested loaders.
## Mental Model
React Router v7/v8 uses a middleware + loader pipeline. Clerk plugs into both layers:
- **Middleware** (`clerkMiddleware()`) — runs on every request, attaches auth to context
- **`rootAuthLoader`** — required in `root.tsx` to pass Clerk state to the client
- **`getAuth(args)`** — called inside any loader/action to get the current user
```
Request → clerkMiddleware() → rootAuthLoader → page loader → component
↓ ↓ ↓
attaches auth injects state getAuth(args)
to context to response reads context
```
## Auth in Loaders
```tsx
import { getAuth } from '@clerk/react-router/server'
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 11 — file references are metadata, not package contents.
clerk-setup16.7 KB
--- name: clerk-setup description: Set up Clerk authentication in any project with the Clerk CLI and official framework quickstarts. Use when adding Clerk, initializing Clerk, scaffolding a new app with Clerk, or migrating an existing authentication system to Clerk. license: MIT allowed-tools: WebFetch compatibility: Requires Node.js 20.9.0 or later for current Clerk SDKs. The Clerk CLI can provision temporary development keys on supported frameworks without a Clerk account. metadata: author: clerk version: 2.6.0 --- # Set up Clerk Use the [Clerk CLI](https://clerk.com/docs/cli) to add authentication. In agent environments, supported frameworks default to accountless setup: `npx -y clerk@latest init` provisions a claimable application and writes temporary development keys without requiring a Clerk account. ## Before you start Show the user this checklist and wait for a yes: ``` Here's what I'll do to get you set up with Clerk. 1. Set up Clerk in this project, or scaffold a new app if this directory is empty. 2. Install Clerk's agent skills for the coding agents on this machine, if they aren't installed yet. 3. Start your app with Clerk installed. Shall I proceed? ``` ## Existing authentication Before `init`, inspect auth dependencies, routes, middleware, sessions, and user records — never environment files. If a different auth provider exists, stop and get approval for a migration plan covering: - Backend API user import, stable external IDs, compatible password hashes, and OAuth continuity. - Protected routes, tokens, session cutover, and rollout strategy. Do not modify or remove existing auth without approval. See the [migration guide](https://clerk.com/docs/guides/development/migrating/overview). ## Existing Clerk projects For a native iOS or macOS app, follow the [iOS setup prompt](https://clerk.com/docs/ios/getting-started/quickstart.md) instead. It reuses the linked application and keeps existing configuration. If the project already uses Clerk, skip `init` in Steps 1a and 1b: a signed-out agent run could create another application and replace the project's Clerk keys. If Clerk already works and the user asked for setup, report that no setup is needed. If the user reports missing keys, restore them through the existing-application branch below. If inspection finds missing provider, middleware, or auth routes, add only those pieces from the matching quickstart in Step 2. Never create a replacement application. Inspect its Clerk package versions before changing anything and use the version table in the [clerk skill](https://clerk.com/.well-known/skills/clerk/SKILL.md) to identify its SDK generation. Preserve that generation unless the user asks to upgrade it, and apply these differences in every step below for Core 2 projects: - React and Expo use `@clerk/clerk-react` and `@clerk/clerk-expo` instead of `@clerk/react` and `@clerk/expo`. - Control components are `<SignedIn>` and `<SignedOut>` instead of `<Show>`. - Next.js `ClerkProvider` can wrap `<html>` instead of going inside `<body>`. - The minimum Node.js version is 18.17.0 instead of 20.9.0. - Themes come from `@clerk/themes` and `@clerk/themes/shadcn.css` instead of `@clerk/ui`. ## Use an existing Clerk application (optional) Follow this branch when the user asks to use an existing Clerk application or an existing Clerk project needs its keys restored. Have them authenticate from their host terminal before targeting account-level resources: ```bash npx -y clerk@latest auth login ``` If they supplied an application ID, keep it for `init` or `link` as appropriate. Otherwise, list the applications: ```bash npx -y clerk@latest apps list --json ``` Show the names and IDs and ask which application to use. Never choose an application for them. For a new Clerk integration, pass the selected ID as `--app <application_id>` to `init`. For a project already using Clerk, do not run `init`. If it is not already linked to the selected application, link it
Preview of the first 4,000 characters. Read full instructions →
Referenced files: 1 — file references are metadata, not package contents.
clerk-swift7.48 KB
---
name: clerk-swift
description: Implement Clerk authentication UI in native Swift apps on iOS and macOS with ClerkKitUI prebuilt views or custom ClerkKit flows. Set up Clerk first with the iOS setup prompt, which uses the Clerk CLI. Do not use for Expo or React Native projects.
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.2.0
compatibility: Requires Xcode and ClerkKit Swift package
---
# Clerk Swift (Native iOS and macOS)
This skill builds Clerk authentication UI in native Swift projects: prebuilt ClerkKitUI views or custom flows on ClerkKit. Setup (SDK, capabilities, native registration, and Clerk initialization) comes first and has its own workflow.
## Activation Rules
Activate this skill when either condition is true:
- The user explicitly asks for Swift, SwiftUI, UIKit, or native iOS or macOS Clerk implementation.
- The project appears to be native Swift (for example `.xcodeproj`, `.xcworkspace`, `Package.swift`, Swift targets).
Do not activate this skill when either condition is true:
- The project is Expo.
- The project is React Native.
If Expo/React Native signals are present, route to the general setup skill instead of this one.
## Set up Clerk first
If Clerk isn't set up yet (no `clerk-ios` package, no `Clerk.configure` call, or no Clerk application chosen), follow the [iOS setup prompt](https://clerk.com/docs/ios/getting-started/quickstart.md) before any UI work. It uses the Clerk CLI to choose a Clerk application, install the SDK, configure capabilities, register the native app, and hand off the remaining Swift integration. The CLI also supplies the publishable key, so don't ask the user to paste one.
If the CLI can't set up the project (for example, Xcode isn't available or the project isn't supported), follow the [manual iOS quickstart](https://clerk.com/docs/ios/getting-started/quickstart.md?manual=1) instead.
If the user already asked for sign-in UI, such as a custom flow, continue here once setup's build check passes. Otherwise, return to this skill when the user wants sign-in UI added or changed.
## What Do You Need?
| Task | Reference |
|------|-----------|
| Prebuilt AuthView / UserButton (fastest) | references/prebuilt.md |
| Custom API-driven auth flows (full control) | references/custom.md |
## Quick Start
| Step | Action |
|------|--------|
| 1 | Confirm the project is native Swift and not Expo/React Native |
| 2 | If Clerk isn't set up, follow the iOS setup prompt first (see above) |
| 3 | Determine the flow type (`prebuilt` or `custom`); ask if it's undecided, then load the matching reference |
| 4 | Check the prerequisites the selected flow needs, such as a package product or capability, and make only the targeted changes that are missing |
| 5 | Implement the flow by following the selected reference |
| 6 | Build the target and report what remains unverified |
## Decision Tree
```text
User asks for Clerk in Swift
|
+-- Expo/React Native project detected?
| |
| +-- YES -> Do not use this skill
| |
| +-- NO -> Continue
|
+-- Clerk set up in this project?
| |
| +-- NO -> Follow the iOS setup prompt (manual quickstart if the CLI can't)
| |
| +-- YES -> Continue
|
+-- Existing auth UI detected?
| |
| +-- Prebuilt views detected -> Load references/prebuilt.md
| |
| +-- Custom flow detected -> Load references/custom.md
| |
| +-- New implementation -> Ask developer prebuilt/custom, then load matching reference
|
+-- Make targeted prerequisite changes for the selected flow
|
+-- Implement using selected flow reference
```
## Flow References
After flow type is known, load exactly one:
- Prebuilt flow: [references/prebuilt.md](references/prebuilt.md)
- Custom flow: [references/custom.md](references/custom.md)
Do not blend the two references in a single implementation unless the developer explicitly asks for a Preview of the first 4,000 characters. Read full instructions →
Referenced files: 3 — file references are metadata, not package contents.
clerk-tanstack-patterns3.75 KB
---
name: clerk-tanstack-patterns
description: 'TanStack React Start auth patterns with @clerk/tanstack-react-start
- createServerFn, beforeLoad guards, loaders, Vite plugin, server middleware. Triggers on: TanStack
auth, createServerFn clerk, beforeLoad protection, TanStack Start middleware.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.0.0
---
# TanStack React Start Patterns
## What Do You Need?
| Task | Reference |
|------|-----------|
| Protect routes with beforeLoad | references/router-guards.md |
| Auth in createServerFn | references/server-functions.md |
| Pass auth to loaders | references/loaders.md |
| Configure Vite + Clerk middleware | references/server-setup.md |
## References
| Reference | Description |
|-----------|-------------|
| `references/router-guards.md` | beforeLoad auth redirect |
| `references/server-functions.md` | createServerFn with auth() |
| `references/loaders.md` | Auth context in loaders |
| `references/server-setup.md` | Vite and request middleware setup |
## Setup
```
npm install @clerk/tanstack-react-start
```
`.env`:
```
VITE_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
```
`src/start.ts` (request middleware):
```typescript
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'
import { createCsrfMiddleware, createStart } from '@tanstack/react-start'
const csrfMiddleware = createCsrfMiddleware({
filter: (ctx) => ctx.handlerType === 'serverFn',
})
export const startInstance = createStart(() => {
return {
requestMiddleware: [csrfMiddleware, clerkMiddleware()],
}
})
```
`src/routes/__root.tsx` — wrap with `<ClerkProvider>`:
```tsx
import { ClerkProvider } from '@clerk/tanstack-react-start'
function RootDocument({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ClerkProvider>
{children}
</ClerkProvider>
</body>
</html>
)
}
```
## Mental Model
TanStack Start uses the `tanstackStart()` Vite plugin. Register CSRF protection before Clerk request middleware in `src/start.ts`; auth then flows through two layers:
1. **Server layer** — `createServerFn` + `auth()` from `@clerk/tanstack-react-start/server`
2. **Router layer** — `beforeLoad` on route definitions, throws `redirect` for unauthenticated
Both layers are server-executed. Client hooks (`useAuth`, `useUser`) are React hooks for the browser side.
## Minimal Pattern
```typescript
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'
const authStateFn = createServerFn().handler(async () => {
const { isAuthenticated, userId } = await auth()
if (!isAuthenticated) {
throw redirect({ to: '/sign-in' })
}
return { userId }
})
export const Route = createFileRoute('/dashboard')({
beforeLoad: async () => await authStateFn(),
})
```
## Common Pitfalls
| Symptom | Cause | Fix |
|---------|-------|-----|
| `auth()` throws "without configuring the middleware" | Missing `clerkMiddleware` in start.ts | Add it after CSRF middleware in `requestMiddleware` |
| `redirect` not thrown | Using `return` instead of `throw` | `throw redirect(...)` in TanStack |
| Wrong import for `auth` | Mixing client/server imports | Server: `@clerk/tanstack-react-start/server` |
| Loader context missing userId | Not passing from beforeLoad | Return from beforeLoad, access via `context` |
| `ClerkProvider` missing | Forgot root wrapping | Add to `__root.tsx` shell component |
## See Also
- `clerk-setup` - Initial Clerk install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations
## Docs
[TanStack React Start SDK](https://clerk.com/docs/tanstack-react-start/getting-started/quickstart)
Referenced files: 12 — file references are metadata, not package contents.
clerk-testing2.28 KB
---
name: clerk-testing
description: E2E testing for Clerk apps. Use with Playwright or Cypress for auth flow
tests.
allowed-tools: WebFetch
license: MIT
metadata:
author: clerk
version: 1.2.1
compatibility: Requires a publishable key and either CLERK_SECRET_KEY or CLERK_TESTING_TOKEN. Keys can be auto-generated by `clerk init` (temporary development keys, no Clerk account required), or pulled from the Clerk Dashboard.
---
# Testing
## Decision Tree
| Framework | Documentation |
|-----------|---------------|
| Overview | https://clerk.com/docs/guides/development/testing/overview |
| Playwright | https://clerk.com/docs/guides/development/testing/playwright/overview |
| Cypress | https://clerk.com/docs/guides/development/testing/cypress/overview |
## Mental Model
Test auth = isolated session state. Each test needs fresh auth context.
- `clerkSetup()` initializes test environment
- `setupClerkTestingToken()` bypasses bot detection
- `storageState` persists auth between tests for speed
## Workflow
1. Identify test framework (Playwright or Cypress)
2. WebFetch the appropriate URL from decision tree above
3. Follow official setup instructions
4. Use development-instance keys only (`pk_test_*` / `sk_test_*`). If the project has no keys yet, `npx clerk@latest init` (the Clerk CLI; see `clerk-setup`) creates a Clerk application and writes development-instance keys to the env file. No Clerk account or Dashboard visit is needed.
## Best Practices
- Use `setupClerkTestingToken()` before navigating to auth pages
- Use test API keys: `pk_test_xxx`, `sk_test_xxx`
- Save auth state with `storageState` for faster tests
- Use `page.waitForSelector('[data-clerk-component]')` for Clerk UI
## Anti-Patterns
| Pattern | Problem | Fix |
|---------|---------|-----|
| Production keys in tests | Security risk | Use `pk_test_*` keys |
| No `setupClerkTestingToken()` | Auth fails | Call before navigation |
| UI-based sign-in every test | Slow tests | Use `storageState` |
## Framework-Specific
**Playwright**: Use `globalSetup` for auth state
**Cypress**: Add `addClerkCommands({ Cypress, cy })` to support file
## See Also
- `clerk-setup` - Install Clerk before adding tests
- `clerk-nextjs-patterns` - Next.js patterns being tested
- [Demo Repo](https://github.com/clerk/clerk-playwright-nextjs/tree/main/e2e)
clerk-vue-patterns2.77 KB
---
name: clerk-vue-patterns
description: 'Vue 3 patterns with Clerk — composables (useAuth, useUser,
useClerk, useOrganization), Vue Router guards, Pinia auth store
integration. Triggers on: vue clerk, useAuth vue, clerk composables,
vue router clerk guard, pinia auth clerk. For Nuxt, use clerk-nuxt-patterns instead.'
license: MIT
allowed-tools: WebFetch
metadata:
author: clerk
version: 1.0.0
---
# Vue Patterns
SDK: `@clerk/vue` v2+ (Vue 3). For Nuxt, use `clerk-nuxt-patterns`.
## What Do You Need?
| Task | Reference |
|------|-----------|
| Composables: useAuth, useUser, useOrganization | references/composables.md |
| Vue Router navigation guards | references/vue-router-guards.md |
| Pinia store with auth state | references/pinia-integration.md |
## Mental Model
Vue uses composables from `@clerk/vue`:
- **`useAuth()`** — reactive `isSignedIn`, `userId`, `signOut`
- **`useUser()`** — reactive `user` object
- **`useClerk()`** — full Clerk instance for advanced operations
- **`useOrganization()`** — reactive `organization`, `membership`
## Setup
### Vue (Plain)
```ts
// main.ts
import { clerkPlugin } from '@clerk/vue'
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.use(clerkPlugin, {
publishableKey: import.meta.env.VITE_CLERK_PUBLISHABLE_KEY,
})
app.mount('#app')
```
## Composables Usage
```vue
<script setup lang="ts">
import { useAuth, useUser } from '@clerk/vue'
const { isSignedIn, userId, signOut } = useAuth()
const { user } = useUser()
</script>
<template>
<div v-if="isSignedIn">
<p>Hello {{ user?.firstName }}</p>
<button @click="signOut()">Sign Out</button>
</div>
<SignInButton v-else />
</template>
```
## Org Switching
```vue
<script setup lang="ts">
import { useOrganizationList } from '@clerk/vue'
const { userMemberships, setActive } = useOrganizationList()
</script>
<template>
<button
v-for="mem in userMemberships.data ?? []"
:key="mem.organization.id"
@click="setActive({ organization: mem.organization.id })"
>
{{ mem.organization.name }}
</button>
</template>
```
## Common Pitfalls
| Symptom | Cause | Fix |
|---------|-------|-----|
| Composables return `undefined` | Not inside `ClerkProvider` tree | Ensure `app.use(clerkPlugin, { publishableKey })` is called |
| `userId` reactive but not updating | Destructuring loses reactivity | Use `const { userId } = useAuth()` (toRefs-style composable, reactive) |
## Import Map
| What | Import |
|------|--------|
| Composables | `@clerk/vue` |
| Plugin setup | `@clerk/vue` |
| Components | `@clerk/vue` |
## See Also
- `clerk-setup` - Initial Clerk install
- `clerk-custom-ui` - Custom flows & appearance
- `clerk-orgs` - B2B organizations
## Docs
- [Vue SDK](https://clerk.com/docs/vue/getting-started/quickstart)
Referenced files: 10 — file references are metadata, not package contents.
clerk-webhooks13 KB
---
name: clerk-webhooks
description: Clerk webhooks for real-time events and data syncing. Verify with verifyWebhook
from the framework-specific package. Handle user, session, organization, billing, and
payment events. Build event-driven features like database sync, notifications, and
integrations.
allowed-tools: WebFetch
license: MIT
metadata:
author: clerk
version: 1.2.0
compatibility: Requires CLERK_WEBHOOK_SIGNING_SECRET (svix signing secret from Clerk dashboard)
---
# Webhooks
Output complete, working webhook handlers with `verifyWebhook(req)` verification in every handler.
## When to Use Webhooks
Webhooks are **asynchronous and eventually consistent**. Delivery is fast but not guaranteed to be immediate, and may occasionally fail (Svix retries on a fixed schedule). Use them for:
- Database sync (a separate users / orgs table that follows Clerk)
- Notifications (welcome emails, Slack pings, internal alerts)
- Integrations triggered by lifecycle events
Do NOT rely on webhook delivery as part of a synchronous flow such as onboarding ("user signs up, then we read X from our DB"). For data the user just created, read it from the [Clerk session token](https://clerk.com/docs/guides/sessions/session-tokens) or call the Backend API directly. Webhooks fill the gap when you need data about *other* users or events the session token doesn't carry.
## Verify Every Webhook
Use `verifyWebhook(req)` from the framework-specific package (`@clerk/nextjs/webhooks`, `@clerk/express/webhooks`, etc.). It reads `CLERK_WEBHOOK_SIGNING_SECRET` automatically and throws on bad signatures. Skipping verification, even for notification-only handlers, exposes the endpoint to spoofed events.
## Keep the Webhook Route Unprotected
Webhook deliveries carry no user session. `verifyWebhook()` is the only check the route needs. A bare `clerkMiddleware()` protects nothing, so the route is already reachable. Don't call `auth.protect()` for `/api/webhooks(.*)`, in middleware or in the handler. A project that does returns `404` for every delivery until that call is removed. See [Ensure the webhook route is public](https://clerk.com/docs/guides/development/webhooks/syncing#ensure-the-webhook-route-is-public).
## Complete Webhook Handler (Next.js App Router)
```typescript
// app/api/webhooks/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks'
import { NextRequest } from 'next/server'
import { db } from '@/lib/db'
export async function POST(req: NextRequest) {
// ALWAYS verify - never skip, even for notification-only handlers
let evt
try {
evt = await verifyWebhook(req) // uses CLERK_WEBHOOK_SIGNING_SECRET automatically
} catch (err) {
console.error('Webhook verification failed:', err)
return new Response('Verification failed', { status: 400 })
}
if (evt.type === 'user.created') {
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
const name = `${first_name ?? ''} ${last_name ?? ''}`.trim()
await db.users.create({ data: { clerkId: id, email, name } })
}
if (evt.type === 'user.updated') {
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
await db.users.update({ where: { clerkId: id }, data: { email, first_name, last_name } })
}
if (evt.type === 'user.deleted') {
const { id } = evt.data
await db.users.delete({ where: { clerkId: id } })
}
if (evt.type === 'organizationMembership.created') {
const { organization, public_user_data, role } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
await db.teamMembers.create({ data: { orgId, userId, role } })
}
if (evt.type === 'organizationMembership.deleted') {
const { organization, public_user_data } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
await db.teamMembers.delete({ where: { orgId_userId:Preview of the first 4,000 characters. Read full instructions →
Referenced files: 2 — file references are metadata, not package contents.
Release notes
Addresses the October 28 review. Tools no longer request analytics-only inputs (context, conversation_id), get_more_tools is removed, and create_user no longer accepts passwords or a free-form request body. set_oauth_provider_credentials, which took OAuth client secrets, is also removed. Organizations and Billing changes now go through patch_instance_config with dry_run instead of enable_organizations and enable_billing, and the review test cases are updated to match. Added update_user, update_user_metadata, organization and membership read tools, configure_mcp_server, check_mcp_server, and list_application_feedback. Bundled skills are updated to the latest Clerk guidance.
Declared in the saved package. Remote tools may change independently.
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package author
- clerk.dev
- Review scenarios
- 5 positive · 3 negativeScenario counts, not test results.
Declared capabilities
- Clerk SDK guidance
- Read Clerk workspace data
- Manage Clerk applications
Package observed Nov 7, 2026.
Technical details
- First seen
- Nov 6, 2026 · 00:00 UTC
- Last seen
- Nov 7, 2026 · 12:00 UTC
- Collection status
- Collected
plugin_asdk_app_6ae4e34683b08191933207035aa0d3ac
Download plugin data (JSON)Plugin details: served from cache. Prepared . Refreshed when plugin data changes or after 6 hours. Your account and Follow status are live.