.claude/skills/ts-fastify/SKILL.md
Fastify is a high-performance Node.js web framework focused on developer experience and low overhead. It features JSON Schema validation, a powerful plugin system, lifecycle hooks, and automatic serialization for blazing-fast APIs.
npx skillsauth add eliferjunior/Claude fastifyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fastify is one of the fastest Node.js web frameworks. It validates requests via JSON Schema, serializes responses automatically, and organizes code through an encapsulated plugin system.
# Create Fastify project
mkdir my-api && cd my-api
npm init -y
npm i fastify @fastify/autoload @fastify/sensible @fastify/cors @fastify/jwt
# Recommended Fastify project layout
src/
├── app.js # App factory
├── server.js # Entry point
├── plugins/ # Shared plugins (db, auth)
│ ├── db.js
│ └── auth.js
├── routes/ # Route modules
│ ├── articles/
│ │ ├── index.js # Route handler
│ │ └── schema.js # JSON schemas
│ └── health.js
└── test/
└── articles.test.js
// src/app.js — application factory with autoload
import Fastify from 'fastify';
import autoload from '@fastify/autoload';
import sensible from '@fastify/sensible';
import cors from '@fastify/cors';
import { join } from 'node:path';
export function buildApp(opts = {}) {
const app = Fastify({ logger: true, ...opts });
app.register(sensible);
app.register(cors, { origin: true });
app.register(autoload, { dir: join(import.meta.dirname, 'plugins') });
app.register(autoload, { dir: join(import.meta.dirname, 'routes'), options: { prefix: '/api' } });
return app;
}
// src/server.js — start the server
import { buildApp } from './app.js';
const app = buildApp();
app.listen({ port: 3000, host: '0.0.0.0' }, (err) => {
if (err) { app.log.error(err); process.exit(1); }
});
// src/routes/articles/schema.js — JSON Schema definitions
export const articleSchema = {
type: 'object',
properties: {
id: { type: 'integer' },
title: { type: 'string' },
body: { type: 'string' },
createdAt: { type: 'string', format: 'date-time' },
},
};
export const createArticleSchema = {
body: {
type: 'object',
required: ['title', 'body'],
properties: {
title: { type: 'string', maxLength: 200 },
body: { type: 'string' },
},
},
response: { 201: articleSchema },
};
// src/routes/articles/index.js — article CRUD routes
import { createArticleSchema } from './schema.js';
export default async function articleRoutes(fastify) {
fastify.get('/', async (request) => {
const { page = 1, limit = 20 } = request.query;
const offset = (page - 1) * limit;
const { rows } = await fastify.db.query(
'SELECT * FROM articles ORDER BY created_at DESC LIMIT $1 OFFSET $2',
[limit, offset]
);
return rows;
});
fastify.get('/:id', async (request, reply) => {
const { rows } = await fastify.db.query('SELECT * FROM articles WHERE id = $1', [request.params.id]);
if (!rows[0]) return reply.notFound();
return rows[0];
});
fastify.post('/', { schema: createArticleSchema, preHandler: [fastify.authenticate] }, async (request, reply) => {
const { title, body } = request.body;
const { rows } = await fastify.db.query(
'INSERT INTO articles (title, body) VALUES ($1, $2) RETURNING *',
[title, body]
);
return reply.code(201).send(rows[0]);
});
}
// src/plugins/db.js — database plugin with pg
import fp from 'fastify-plugin';
import pg from 'pg';
export default fp(async function dbPlugin(fastify) {
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
fastify.decorate('db', pool);
fastify.addHook('onClose', () => pool.end());
});
// src/plugins/auth.js — JWT auth plugin
import fp from 'fastify-plugin';
import jwt from '@fastify/jwt';
export default fp(async function authPlugin(fastify) {
fastify.register(jwt, { secret: process.env.JWT_SECRET || 'dev-secret' });
fastify.decorate('authenticate', async function (request, reply) {
try {
await request.jwtVerify();
} catch (err) {
reply.unauthorized();
}
});
});
// src/app.js — lifecycle hooks example (add inside buildApp)
app.addHook('onRequest', async (request) => {
request.startTime = process.hrtime.bigint();
});
app.addHook('onResponse', async (request, reply) => {
const duration = Number(process.hrtime.bigint() - request.startTime) / 1e6;
request.log.info({ duration: `${duration.toFixed(2)}ms`, status: reply.statusCode }, 'request completed');
});
// src/app.js — custom error handler (add inside buildApp)
app.setErrorHandler((error, request, reply) => {
request.log.error(error);
const status = error.statusCode || 500;
reply.code(status).send({
error: error.name,
message: status === 500 ? 'Internal Server Error' : error.message,
});
});
// src/test/articles.test.js — testing with built-in inject
import { test } from 'node:test';
import assert from 'node:assert';
import { buildApp } from '../app.js';
test('GET /api/articles returns 200', async () => {
const app = buildApp({ logger: false });
const response = await app.inject({ method: 'GET', url: '/api/articles' });
assert.strictEqual(response.statusCode, 200);
await app.close();
});
fastify-plugin (fp) for plugins that should share the same encapsulation context@fastify/autoload to auto-register plugins and routes from directoriesfastify.decorate) for shared services (db, cache)@fastify/sensible for .notFound(), .unauthorized(), etc. helpersreply.send()development
Expert guidance for Fireworks AI, the platform for running open-source LLMs (Llama, Mixtral, Qwen, etc.) with enterprise-grade speed and reliability. Helps developers integrate Fireworks' inference API, fine-tune models, and deploy custom model endpoints with function calling and structured output support.
development
Convert any website into clean, structured data with Firecrawl — API-first web scraping service. Use when someone asks to "turn a website into markdown", "scrape website for LLM", "Firecrawl", "extract website content as clean text", "crawl and convert to structured data", or "scrape website for RAG". Covers single-page scraping, full-site crawling, structured extraction, and LLM-ready output.
tools
Expert guidance for Firebase, Google's platform for building and scaling web and mobile applications. Helps developers set up authentication, Firestore/Realtime Database, Cloud Functions, hosting, storage, and analytics using Firebase's SDK and CLI.
development
When the user needs to build file upload functionality for a web application. Use when the user mentions "file upload," "image upload," "upload endpoint," "multipart upload," "presigned URL," "S3 upload," "file validation," "upload to cloud storage," or "accept user files." Handles upload endpoints, file validation (type, size, magic bytes), cloud storage integration, and upload status tracking. For image/video processing after upload, see media-transcoder.