Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    oriolrius

    fastify

    oriolrius/fastify
    Coding
    4

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Expert guidance for Fastify web framework including server setup, routing, plugins, hooks, validation, error handling, and TypeScript integration...

    SKILL.md

    Fastify

    Expert assistance with Fastify - Fast and low overhead web framework for Node.js.

    Overview

    Fastify is a highly performant web framework:

    • Fast: One of the fastest Node.js frameworks
    • Low Overhead: Minimal resource consumption
    • Schema-based: JSON Schema validation
    • TypeScript: Excellent TypeScript support
    • Plugin Architecture: Extensible with plugins
    • Logging: Built-in logging with Pino

    Installation

    npm install fastify
    npm install --save-dev @types/node
    
    # Common plugins
    npm install @fastify/cors          # CORS support
    npm install @fastify/websocket     # WebSocket support
    npm install @fastify/cookie        # Cookie parsing
    npm install @fastify/jwt           # JWT authentication
    npm install @fastify/helmet        # Security headers
    npm install @fastify/rate-limit    # Rate limiting
    

    Quick Start

    import Fastify from 'fastify';
    
    const server = Fastify({
      logger: true, // Enable Pino logging
    });
    
    server.get('/ping', async (request, reply) => {
      return { pong: 'it worked!' };
    });
    
    await server.listen({ port: 3000, host: '0.0.0.0' });
    console.log('Server listening on http://localhost:3000');
    

    Server Configuration

    import Fastify from 'fastify';
    
    const server = Fastify({
      logger: {
        level: 'info',
        transport: {
          target: 'pino-pretty', // Pretty printing in development
        },
      },
      bodyLimit: 1048576, // 1MB body limit
      caseSensitive: true, // Case-sensitive routes
      ignoreTrailingSlash: false,
      requestIdHeader: 'x-request-id',
      requestIdLogLabel: 'reqId',
      trustProxy: true, // Trust proxy headers
    });
    

    Routing

    Basic Routes

    // GET
    server.get('/users', async (request, reply) => {
      return [{ id: 1, name: 'John' }];
    });
    
    // POST
    server.post('/users', async (request, reply) => {
      const { name, email } = request.body;
      return { id: 2, name, email };
    });
    
    // PUT
    server.put('/users/:id', async (request, reply) => {
      const { id } = request.params;
      const { name } = request.body;
      return { id, name };
    });
    
    // DELETE
    server.delete('/users/:id', async (request, reply) => {
      const { id } = request.params;
      return { deleted: id };
    });
    
    // PATCH
    server.patch('/users/:id', async (request, reply) => {
      return { updated: true };
    });
    

    Route Parameters

    // URL parameters
    server.get<{
      Params: { id: string };
    }>('/users/:id', async (request, reply) => {
      const { id } = request.params; // Typed!
      return { id };
    });
    
    // Multiple parameters
    server.get<{
      Params: { userId: string; postId: string };
    }>('/users/:userId/posts/:postId', async (request, reply) => {
      const { userId, postId } = request.params;
      return { userId, postId };
    });
    
    // Query parameters
    server.get<{
      Querystring: { search?: string; limit?: number };
    }>('/search', async (request, reply) => {
      const { search, limit = 10 } = request.query;
      return { search, limit };
    });
    

    TypeScript Types

    import { FastifyRequest, FastifyReply } from 'fastify';
    
    interface CreateUserBody {
      name: string;
      email: string;
    }
    
    interface UserParams {
      id: string;
    }
    
    server.post<{
      Body: CreateUserBody;
    }>('/users', async (request, reply) => {
      const { name, email } = request.body; // Fully typed
      return { id: '1', name, email };
    });
    
    server.get<{
      Params: UserParams;
    }>('/users/:id', async (request, reply) => {
      const { id } = request.params;
      return { id };
    });
    

    Validation

    JSON Schema Validation

    const createUserSchema = {
      body: {
        type: 'object',
        required: ['name', 'email'],
        properties: {
          name: { type: 'string', minLength: 2 },
          email: { type: 'string', format: 'email' },
          age: { type: 'number', minimum: 18 },
        },
      },
      response: {
        201: {
          type: 'object',
          properties: {
            id: { type: 'string' },
            name: { type: 'string' },
            email: { type: 'string' },
          },
        },
      },
    };
    
    server.post('/users', {
      schema: createUserSchema,
    }, async (request, reply) => {
      const { name, email, age } = request.body;
      reply.status(201);
      return { id: '1', name, email };
    });
    

    Plugins

    Register Plugins

    import cors from '@fastify/cors';
    import helmet from '@fastify/helmet';
    import rateLimit from '@fastify/rate-limit';
    
    // CORS
    await server.register(cors, {
      origin: true, // Reflect origin
      credentials: true,
    });
    
    // Security headers
    await server.register(helmet);
    
    // Rate limiting
    await server.register(rateLimit, {
      max: 100, // 100 requests
      timeWindow: '1 minute',
    });
    

    Custom Plugin

    import fp from 'fastify-plugin';
    
    const myPlugin = fp(async (fastify, options) => {
      // Add decorator
      fastify.decorate('myUtility', () => {
        return 'Hello from plugin!';
      });
    
      // Add hook
      fastify.addHook('onRequest', async (request, reply) => {
        // Do something on every request
      });
    }, {
      name: 'my-plugin',
      fastify: '4.x',
    });
    
    await server.register(myPlugin);
    
    // Use decorator
    server.get('/test', async (request, reply) => {
      return { message: server.myUtility() };
    });
    

    Hooks

    // Application hooks
    server.addHook('onRequest', async (request, reply) => {
      // Called before route handler
      request.log.info('Incoming request');
    });
    
    server.addHook('preHandler', async (request, reply) => {
      // Called after validation, before handler
      if (!request.headers.authorization) {
        reply.code(401).send({ error: 'Unauthorized' });
      }
    });
    
    server.addHook('onSend', async (request, reply, payload) => {
      // Called before sending response
      return payload;
    });
    
    server.addHook('onResponse', async (request, reply) => {
      // Called after response sent
      request.log.info({ responseTime: reply.getResponseTime() });
    });
    
    server.addHook('onError', async (request, reply, error) => {
      // Called on error
      request.log.error(error);
    });
    

    Error Handling

    // Custom error handler
    server.setErrorHandler((error, request, reply) => {
      request.log.error(error);
    
      if (error.validation) {
        reply.status(400).send({
          error: 'Validation Error',
          message: error.message,
          details: error.validation,
        });
        return;
      }
    
      reply.status(error.statusCode || 500).send({
        error: error.name,
        message: error.message,
      });
    });
    
    // Throw errors in routes
    server.get('/error', async (request, reply) => {
      throw new Error('Something went wrong!');
    });
    
    // Send error responses
    server.get('/not-found', async (request, reply) => {
      reply.code(404).send({ error: 'Not found' });
    });
    

    tRPC Integration

    import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
    import { appRouter } from './trpc/router';
    import { createContext } from './trpc/context';
    
    // Register tRPC
    await server.register(fastifyTRPCPlugin, {
      prefix: '/trpc',
      trpcOptions: {
        router: appRouter,
        createContext,
      },
    });
    

    WebSocket Support

    import websocket from '@fastify/websocket';
    
    await server.register(websocket);
    
    server.get('/ws', { websocket: true }, (connection, request) => {
      connection.socket.on('message', (message) => {
        connection.socket.send('Hello from server!');
      });
    });
    

    Testing

    import { test } from 'node:test';
    import Fastify from 'fastify';
    
    test('GET /ping returns pong', async (t) => {
      const server = Fastify();
    
      server.get('/ping', async () => {
        return { pong: 'it worked!' };
      });
    
      const response = await server.inject({
        method: 'GET',
        url: '/ping',
      });
    
      t.assert.strictEqual(response.statusCode, 200);
      t.assert.deepStrictEqual(response.json(), { pong: 'it worked!' });
    });
    

    Best Practices

    1. Use Plugins: Encapsulate functionality in plugins
    2. Schema Validation: Always validate input with JSON Schema
    3. Error Handling: Set up global error handler
    4. Logging: Use built-in Pino logger
    5. TypeScript: Leverage type safety
    6. Hooks: Use hooks for cross-cutting concerns
    7. Async/Await: Use async handlers
    8. Testing: Use fastify.inject() for testing
    9. Performance: Enable HTTP/2 for better performance
    10. Security: Use @fastify/helmet for security headers

    Resources

    • Documentation: https://www.fastify.io/docs/latest/
    • GitHub: https://github.com/fastify/fastify
    • Plugins: https://www.fastify.io/ecosystem/
    Recommended Servers
    Astro Docs
    Astro Docs
    Svelte
    Svelte
    Cloudflare
    Cloudflare
    Repository
    oriolrius/pki-manager-web
    Files