Fastify Forge empowers developers to build lightning-fast, enterprise-grade REST APIs with zero configuration overhead. Powered by Fastify, the best framework in the town for Node.js, TypeScript and battle-tested plugins, this isn't just another boilerplateβit's your secret weapon for backend development.
Quick Navigation: π Quick Start β’ π Features β’ π οΈ Development Guide β’ π― Examples
- β‘ Why Use Fastify Forge?
- π Quick Start
- π οΈ What Makes Fastify Forge Special
- π Development Guide
- π― Real-World Examples
- π’ Production Deployment
- π§ͺ Testing & Quality Assurance
- π§ Advanced Configuration
- π€ Contributing
"From idea to production in under 5 minutes" - That's the Fastify Forge promise.
- π₯ Performance First: Fastify is the fastest Node.js frameworks
- π‘οΈ Enterprise Security: Built-in CORS, Helmet, Rate Limiting, and Authentication
- π Type Safety: Full TypeScript support with runtime validation using TypeBox
- π Auto Documentation: Swagger/OpenAPI docs generated automatically
- βοΈ Zero Config: Works out of the box, customize when you need to
- π³ Docker Ready: Production-ready containerization included
- Startups building MVPs that need to scale
- Enterprise teams requiring robust, maintainable APIs
- Full-stack developers who want backend peace of mind
- DevOps engineers seeking deployment simplicity
Create a new project in seconds:
npx fastify-forge@latest
cd my-api
# Install dependencies
pnpm install
# Start the development server with hot-reload
pnpm dev
That's it! Your API is now running at http://localhost:3000
- β
API Documentation: Visit
http://localhost:3000/documentation
- β
Health Check:
GET /health
endpoint ready to use - β Type Safety: Full TypeScript support with auto-completion
- β Authentication: Auth system ready to configure
- β Database: PostgreSQL integration with Drizzle ORM
curl http://localhost:3000/health
# Response: {"status":"ok"}
// Built-in security headers, CORS, and rate limiting
// Zero configuration required!
app.register(helmet);
app.register(cors);
app.register(rateLimit, {
max: 100,
timeWindow: '1 minute'
});
// Define your API with full type safety
const UserSchema = Type.Object({
id: Type.String(),
email: Type.String({ format: 'email' }),
name: Type.String({ minLength: 1 })
});
app.post('/users', {
schema: {
body: UserSchema,
response: {
201: UserSchema
}
}
}, async (request, reply) => {
// request.body is fully typed!
const user = await createUser(request.body);
return reply.code(201).send(user);
});
Beautiful, interactive API documentation generated automatically from your TypeScript schemas
- Hot Reload: Instant development feedback
- ESLint + Prettier: Code quality enforced
- Husky: Pre-commit hooks for consistency
- Jest: Comprehensive testing setup
- PM2: Production process management
fastify-forge/
βββ src/
β βββ app.ts # Application setup & plugins
β βββ server.ts # Server entry point
β βββ auth.ts # Authentication logic
β βββ config/
β β βββ env.config.ts # Environment configuration
β βββ db/
β β βββ index.ts # Database connection
β β βββ schema.ts # Database schema
β βββ plugins/
β β βββ external/ # Third-party plugins
β β βββ internal/ # Custom plugins
β βββ routes/
β βββ health.ts # Health check endpoint
β βββ api/v1/ # Versioned API routes
βββ test/ # Test files
βββ docker-compose.yml # Docker setup
βββ process.yml # PM2 configuration
-
Copy the environment template:
cp .env.example .env
-
Configure your environment variables:
# Database POSTGRES_HOST=localhost POSTGRES_USER=your_user POSTGRES_PASSWORD=your_password POSTGRES_DB=your_database POSTGRES_PORT=5432 # Server HOST=localhost PORT=3000 NODE_ENV=development LOG_LEVEL=info
-
Validate configuration:
pnpm dev # β Configuration validated automatically on startup
Create a new route file in src/routes/
:
import type { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox';
import { Type } from '@sinclair/typebox';
const UserSchema = Type.Object({
id: Type.String(),
name: Type.String(),
email: Type.String({ format: 'email' })
});
const usersRoute: FastifyPluginAsyncTypebox = async (app) => {
app.route({
url: '/users',
method: 'GET',
schema: {
tags: ['Users'],
response: {
200: Type.Array(UserSchema)
}
},
handler: async () => {
return [
{ id: '1', name: 'John Doe', email: '[email protected]' }
];
}
});
};
export default usersRoute;
Add custom functionality in src/plugins/internal/
:
import type { FastifyPluginAsync } from 'fastify';
import fp from 'fastify-plugin';
const myPlugin: FastifyPluginAsync = async (app) => {
app.decorate('myUtility', () => {
return 'Hello from my plugin!';
});
};
export default fp(myPlugin);
Using Drizzle ORM for type-safe database operations:
import { eq } from 'drizzle-orm';
import { users } from '../db/schema.js';
// In your route handler
const getUsers = async () => {
return await app.db.select().from(users);
};
const getUserById = async (id: string) => {
return await app.db.select().from(users).where(eq(users.id, id));
};
const protectedRoute: FastifyPluginAsyncTypebox = async (app) => {
// Apply authentication hook to all routes in this plugin
app.addHook('preHandler', app.authenticate);
app.route({
url: '/profile',
method: 'GET',
schema: {
tags: ['User'],
security: [{ bearerAuth: [] }]
},
handler: async (request) => {
// request.user is available after authentication
return { user: request.user };
}
});
};
const uploadRoute: FastifyPluginAsyncTypebox = async (app) => {
app.route({
url: '/upload',
method: 'POST',
schema: {
tags: ['Files'],
consumes: ['multipart/form-data']
},
handler: async (request, reply) => {
const data = await request.file();
if (!data) {
return reply.badRequest('No file uploaded');
}
// Process the file...
return { filename: data.filename, size: data.file.readableLength };
}
});
};
const postsRoute: FastifyPluginAsyncTypebox = async (app) => {
app.route({
url: '/posts',
method: 'POST',
schema: {
tags: ['Posts'],
body: Type.Object({
title: Type.String({ minLength: 1 }),
content: Type.String({ minLength: 1 })
}),
response: {
201: Type.Object({
id: Type.String(),
title: Type.String(),
content: Type.String(),
createdAt: Type.String()
})
}
},
handler: async (request, reply) => {
const { title, content } = request.body;
const [post] = await app.db.insert(posts).values({
title,
content,
authorId: request.user.id
}).returning();
return reply.code(201).send(post);
}
});
};
# Build the image
docker build -t my-api .
# Run with docker-compose
docker-compose up -d
# Build for production
pnpm build
# Start with PM2
pnpm pm2
# Monitor processes
pm2 monit
Vercel/Netlify:
pnpm build
# Deploy the `dist` folder
AWS/GCP/Azure:
- Use the included
Dockerfile
- Set environment variables
- Configure health checks on
/health
- Environment variables configured
- Database migrations run
- SSL/TLS certificates in place
- Rate limiting configured
- Monitoring and logging set up
- Health checks responding
- Load balancer configured (if needed)
# Run all tests
pnpm test
# Run tests with coverage report
pnpm test:lcov
# Run linting
pnpm lint
Fastify Forge aims for 100% test coverage. The test setup includes:
- Unit Tests: Individual function testing
- Integration Tests: Route and plugin testing
- E2E Tests: Full application flow testing
- ESLint: Catch code issues early powered by Neostandard
- Husky: Pre-commit hooks
- Commitlint: Conventional commit messages
Extend src/config/env.config.ts
:
const schema = Type.Object({
// Existing variables...
REDIS_URL: Type.String(),
SMTP_HOST: Type.String(),
JWT_SECRET: Type.String({ minLength: 32 }),
API_RATE_LIMIT: Type.Number({ default: 100 })
});
Modify plugin settings in src/app.ts
:
// Custom rate limiting
await app.register(rateLimit, {
max: env.API_RATE_LIMIT,
timeWindow: '1 minute',
keyGenerator: (request) => request.ip
});
const server = Fastify({
logger: {
level: env.LOG_LEVEL,
transport: env.NODE_ENV === 'development' ? {
target: 'pino-pretty',
options: { colorize: true }
} : undefined
}
});
We welcome contributions! Here's how you can help:
- Check existing issues first
- Provide detailed reproduction steps
- Include environment information
- Open an issue with the
enhancement
label - Describe the use case and benefits
- Consider implementation approaches
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit changes:
git commit -m 'Add amazing feature'
- Push to branch:
git push origin feature/amazing-feature
- Open a Pull Request
# Clone the repo
git clone https://github.com/flaviodelgrosso/fastify-forge.git
cd fastify-forge
# Install dependencies
pnpm install
# Start development
pnpm dev
# Run tests
pnpm test
This project is licensed under the MIT License.
- Fastify Team for the amazing framework
- TypeBox for type-safe schemas
- All the contributors who make this project better
Ready to forge your next API? π₯
npx fastify-forge@latest
Happy coding! π