Does Fastify Work With Clerk?
Fastify and Clerk work together seamlessly for building authenticated applications with minimal setup.
Quick Facts
How Fastify Works With Clerk
Clerk provides an official Fastify plugin (@clerk/fastify) that handles authentication middleware, session management, and user context injection. The plugin integrates with Fastify's request/reply lifecycle, making it straightforward to protect routes and access authenticated user data. You install the plugin, configure it with your Clerk API keys, and it automatically validates JWTs or session cookies depending on your frontend setup. The developer experience is excellent—Clerk handles token refresh, user object population, and CORS concerns automatically. Fastify's lightweight nature pairs well with Clerk's client-side SDKs, letting you build performant full-stack apps without boilerplate. The plugin works with both traditional server-rendered templates and headless API backends feeding React/Vue frontends. Architecture-wise, Clerk manages identity at the edge while Fastify focuses purely on business logic, creating clean separation of concerns.
Best Use Cases
Quick Setup
npm install fastify @clerk/fastify dotenvimport Fastify from 'fastify';
import { clerkPlugin } from '@clerk/fastify';
const fastify = Fastify();
await fastify.register(clerkPlugin, {
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
secretKey: process.env.CLERK_SECRET_KEY,
});
fastify.get('/protected', async (request, reply) => {
await request.clerkAuthenticateRequest();
return { userId: request.auth.userId, message: 'Welcome!' };
});
fastify.get('/public', (request, reply) => {
return { message: 'No auth required' };
});
await fastify.listen({ port: 3000 });Known Issues & Gotchas
CORS configuration must align between Clerk dashboard and Fastify app, or token validation fails
Fix: Register @fastify/cors before @clerk/fastify plugin and whitelist your frontend origin in Clerk dashboard under API & Keys > CORS
Using @clerk/fastify with database queries requires explicit session management since Clerk doesn't automatically attach user ID to requests
Fix: Access authenticated user via request.auth.userId after Clerk middleware runs, then query your database accordingly
Clerk's webhook signatures use raw request body, so body parsing must happen after signature verification
Fix: Configure Fastify to skip automatic body parsing for Clerk webhook routes, or use Clerk's built-in webhook handler
Alternatives
- •Express.js + Clerk (@clerk/express) — more mainstream but heavier framework
- •Next.js + Clerk — opinionated full-stack framework with built-in Clerk support
- •Hono + Auth0 — lightweight alternative using Auth0 instead of Clerk for auth
Resources
Related Compatibility Guides
Explore more compatibility guides