Fastify Better Auth is a Fastify plugin that simplifies the integration of the Better Auth library into your Fastify applications. This plugin automatically registers authentication routes and provides utilities to access the auth instance and session data in your application.
- 🚀 Easy integration with Better Auth
- 🛡️ Automatic route registration for authentication endpoints
- 🔧 Type-safe decorator access to auth instance
- ⚡ Compatible with Fastify 5.x and Better Auth 1.x
- Fastify 5.x
- Better Auth 1.x
npm install fastify-better-auth
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
export const auth = betterAuth({
trustedOrigins: [process.env.AUTH_URL],
database: drizzleAdapter(db, {
provider: 'pg',
usePlural: true,
}),
emailAndPassword: {
enabled: true,
},
});
import type { FastifyInstance } from 'fastify';
import FastifyBetterAuth from 'fastify-better-auth';
import fp from 'fastify-plugin';
import { auth } from './auth.js';
async function authPlugin(fastify: FastifyInstance) {
await fastify.register(FastifyBetterAuth, { auth });
}
export default fp(authPlugin, {
name: 'auth-plugin',
});
import FastifyBetterAuth, { type FastifyBetterAuthOptions } from 'fastify-better-auth';
import { auth } from './auth.js';
export const autoConfig: FastifyBetterAuthOptions = {
auth
};
export default FastifyBetterAuth;
Once registered, the plugin automatically creates authentication routes under /api/auth/*
and decorates your Fastify instance with the auth utilities.
interface FastifyBetterAuthOptions<AuthOptions extends BetterAuthOptions = BetterAuthOptions> {
auth: BetterAuthInstance<AuthOptions>;
}
auth
: A Better Auth instance created withbetterAuth()
The plugin automatically registers the following authentication routes:
POST /api/auth/sign-in
- Sign in with email/passwordPOST /api/auth/sign-up
- Create a new accountPOST /api/auth/sign-out
- Sign out the current userGET /api/auth/session
- Get current session- And all other Better Auth endpoints...
When registering the plugin, it decorates the Fastify instance with the Better Auth instance. You can use getAuthDecorator()
to access the auth instance in your routes or hooks.
Note:
getDecorator
API provided by Fastify is the recommended way instead of using module augmentation.getAuthDecorator()
is a wrapper around it and is generic and type-safe. It's recommended to use it with the type of the auth options you passed to the auth instance, especially if you're using plugins that extend the auth instance with additional methods.
import { getAuthDecorator } from 'fastify-better-auth';
import type { FastifyInstance } from 'fastify';
// In your route handler
fastify.get('/protected', async (request, reply) => {
const auth = getAuthDecorator<typeof authOptions>(fastify);
// Use auth.api methods here
});
Here's how to create an authentication hook to protect routes and access session data:
import { fromNodeHeaders } from 'better-auth/node';
import type { FastifyInstance } from 'fastify';
import { getAuthDecorator } from 'fastify-better-auth';
import { auth } from './auth.js';
async function authHook(fastify: FastifyInstance) {
// Decorate the request with session
fastify.decorateRequest('session');
fastify.addHook('preHandler', async (request, reply) => {
const authInstance = getAuthDecorator<typeof auth.options>(fastify);
const session = await authInstance.api.getSession({
headers: fromNodeHeaders(request.headers),
});
if (!session?.user) {
return reply.unauthorized('You must be logged in to access this resource.');
}
request.setDecorator('session', session);
});
}
export default authHook;
import type { FastifyInstance } from 'fastify';
import { getAuthDecorator } from 'fastify-better-auth';
export default async function routes(fastify: FastifyInstance) {
// Public route
fastify.get('/health', async () => {
return { status: 'ok' };
});
// Protected route
fastify.get('/profile', {
preHandler: async (request, reply) => {
const auth = getAuthDecorator(fastify);
const session = await auth.api.getSession({
headers: fromNodeHeaders(request.headers),
});
if (!session?.user) {
return reply.code(401).send({ error: 'Unauthorized' });
}
request.user = session.user;
}
}, async (request) => {
return { user: request.user };
});
}
You can find a complete working example in the fastify-forge template, which demonstrates:
- Full authentication setup
- Protected routes
- Session management
- Production-ready configuration
Contributions are welcome! Please feel free to submit a Pull Request.
- Clone the repository
- Install dependencies:
npm install
- Run tests:
npm test
- Build the project:
npm run build
See CHANGELOG.md for details about changes in each version.
This project is licensed under the ISC License - see the LICENSE file for details.