From harness-claude
Builds performant Fastify APIs with schema validation, plugins, decorators, and hooks. Includes TypeBox type-safe routes and modular plugin architecture.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:node-fastify-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Build performant APIs with Fastify using schema validation, plugins, decorators, and hooks
Build performant APIs with Fastify using schema validation, plugins, decorators, and hooks
import Fastify from 'fastify';
const fastify = Fastify({ logger: true });
fastify.get('/health', async () => ({ status: 'ok' }));
await fastify.listen({ port: 3000, host: '0.0.0.0' });
const createUserSchema = {
body: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
},
},
response: {
201: {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' },
email: { type: 'string' },
},
},
},
} as const;
fastify.post('/users', { schema: createUserSchema }, async (request, reply) => {
const user = await createUser(request.body);
reply.status(201).send(user);
});
import { Type, Static } from '@sinclair/typebox';
const CreateUserBody = Type.Object({
name: Type.String({ minLength: 1 }),
email: Type.String({ format: 'email' }),
});
type CreateUserBody = Static<typeof CreateUserBody>;
fastify.post<{ Body: CreateUserBody }>(
'/users',
{
schema: { body: CreateUserBody },
},
async (request) => {
const { name, email } = request.body; // Fully typed
return createUser({ name, email });
}
);
import fp from 'fastify-plugin';
// db.ts — database plugin
export default fp(async (fastify) => {
const db = await connectDatabase();
fastify.decorate('db', db);
fastify.addHook('onClose', async () => {
await db.disconnect();
});
});
// Register plugins
await fastify.register(import('./plugins/db'));
await fastify.register(import('./routes/users'), { prefix: '/api/users' });
// routes/users.ts
import { FastifyPluginAsync } from 'fastify';
const userRoutes: FastifyPluginAsync = async (fastify) => {
fastify.get('/', async () => {
return fastify.db.user.findMany();
});
fastify.get('/:id', async (request) => {
const { id } = request.params as { id: string };
const user = await fastify.db.user.findUnique({ where: { id } });
if (!user) throw fastify.httpErrors.notFound('User not found');
return user;
});
};
export default userRoutes;
// Authentication hook
fastify.addHook('preHandler', async (request, reply) => {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw fastify.httpErrors.unauthorized();
request.user = await verifyToken(token);
});
// Logging hook
fastify.addHook('onResponse', async (request, reply) => {
request.log.info({
url: request.url,
method: request.method,
statusCode: reply.statusCode,
duration: reply.elapsedTime,
});
});
fastify.setErrorHandler((error, request, reply) => {
request.log.error(error);
if (error.validation) {
reply.status(400).send({ errors: error.validation });
return;
}
reply.status(error.statusCode ?? 500).send({
error: error.message || 'Internal Server Error',
});
});
Fastify is designed for speed. It uses JSON Schema for validation and serialization, achieving 2-5x higher throughput than Express for JSON APIs.
Why Fastify is faster:
fast-json-stringify)ajv)Plugin encapsulation: Fastify plugins run in isolated contexts. Decorators and hooks registered inside a plugin are scoped to that plugin and its children, not the entire application.
fp (fastify-plugin): Wrapping a plugin with fp() breaks encapsulation, making decorators available to the parent scope. Use fp for plugins that add shared functionality (database, auth); use regular plugins for routes.
Trade-offs:
https://fastify.dev/docs/latest/
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeBuilds REST APIs with Fastify and TypeScript, including route creation, TypeBox schema validation, request handling, and plugin architecture.
Provides Fastify 5 best practices, API reference, and patterns for routes, plugins, hooks, validation, error handling, and TypeScript. Use for writing routes/plugins/hooks, looking up APIs, debugging lifecycle/validation issues, or reviewing anti-patterns.
Implements Node.js backend patterns with Express/Fastify for middleware, error handling, auth, DB integration, REST/GraphQL APIs, microservices, and WebSockets.