npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2026 – Pkg Stats / Ryan Hefner

fastify-forge

v3.0.2

Published

πŸš€ Fastify monorepo template for building scalable, high-performance Node.js web applications with ease

Readme

⚑ Fastify Forge

A production-ready Fastify monorepo template β€” scaffold, build, and ship high-performance Node.js APIs in seconds.

npm version License: MIT Node.js pnpm TypeScript Fastify


Why Fastify Forge?

Starting a new Node.js API project means wiring up the same boilerplate every time β€” auth, validation, logging, CORS, rate-limiting, OpenAPI docs, database migrations… Fastify Forge ships all of it, pre-configured and production-grade, in a single npx command.

Built on Fastify 5 β€” one of the fastest HTTP frameworks for Node.js β€” and organised as an Nx monorepo, the template gives you a clean, scalable foundation you can grow into without ever fighting the scaffolding again.


✨ Features

| Category | What's included | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- | | πŸš€ Performance | Fastify 5 + Pino structured logging + @fastify/under-pressure overload protection | | πŸ” Authentication | Better Auth with email/password, admin plugin, session caching & cookie management | | πŸ—„οΈ Database | Drizzle ORM + PostgreSQL 17 with pre-built users, sessions & accounts schema | | βœ… Validation | End-to-end type-safe schemas via TypeBox + @fastify/type-provider-typebox | | πŸ“– OpenAPI | Swagger UI at /docs + Better Auth's OpenAPI integration, auto-generated from route schemas | | πŸ›‘οΈ Security | @fastify/helmet, @fastify/cors, @fastify/rate-limit (with 404-route scan protection) | | πŸ“ Auto-loading | Plugin & route discovery via @fastify/autoload β€” drop a file, it's registered | | πŸͺ Route Hooks | Cascading auth.hook.ts pattern keeps authentication logic out of route handlers | | βš™οΈ Config | Type-safe environment variables via @fastify/env + TypeBox schema | | 🐳 Docker | PostgreSQL 17 via docker-compose.yaml with health checks and persistent volumes | | πŸ”„ Graceful shutdown | close-with-grace ensures in-flight requests complete before the server exits | | πŸ—οΈ Monorepo | Nx workspace with affected-only CI, build caching, and Docker targets | | 🎨 DX | Husky, commitlint (Conventional Commits), Prettier, ESLint 9 flat config, Changesets, syncpack | | πŸ› οΈ CLI | Interactive scaffolder β€” npx fastify-forge to clone, configure, and initialise a new project |


πŸ“¦ Tech Stack

| Layer | Technology | | --------------- | ------------------ | | Runtime | Node.js β‰₯ 24 | | Framework | Fastify 5 | | Language | TypeScript 5 | | ORM | Drizzle ORM | | Database | PostgreSQL 17 | | Auth | Better Auth | | Logging | Pino + pino-pretty | | Validation | TypeBox | | Monorepo | Nx | | Package manager | pnpm 10 |


πŸš€ Quick Start

Option A β€” CLI scaffolder (recommended)

npx fastify-forge --name my-api

The interactive CLI will:

  1. Clone the template into ./my-api
  2. Strip git history and set up a fresh repo
  3. Copy .env.example β†’ .env
  4. Optionally initialise git and install dependencies

Option B β€” Clone manually

git clone https://github.com/flaviodelgrosso/fastify-forge.git my-api
cd my-api
pnpm install

🏁 Getting Started

1. Configure environment variables

Copy the example file and fill in your values:

cp apps/api/.env.example apps/api/.env

| Variable | Description | Default | | -------------------- | ------------------------------------------------------------------ | ----------- | | HOST | Server bind address | localhost | | PORT | Server port | 8080 | | LOG_LEVEL | Pino log level (trace | debug | info | warn | error) | info | | POSTGRES_HOST | PostgreSQL host | β€” | | POSTGRES_PORT | PostgreSQL port | 5432 | | POSTGRES_USER | PostgreSQL user | β€” | | POSTGRES_PASSWORD | PostgreSQL password | β€” | | POSTGRES_DB | PostgreSQL database name | β€” | | BETTER_AUTH_SECRET | Secret key for Better Auth (min 32 chars) | β€” |

2. Start the database

docker compose up -d

3. Run database migrations

pnpm --filter @fastify-forge/db db:push

4. Start the development server

pnpm start

The API is now running at http://localhost:8080 πŸŽ‰


πŸ“ Project Structure

fastify-forge/
β”œβ”€β”€ apps/
β”‚   └── api/                    # Main Fastify application
β”‚       └── src/
β”‚           β”œβ”€β”€ main.ts         # Server entry point & graceful shutdown
β”‚           β”œβ”€β”€ app.ts          # Plugin & route registration, error handlers
β”‚           β”œβ”€β”€ auth.ts         # Better Auth configuration
β”‚           β”œβ”€β”€ plugins/
β”‚           β”‚   β”œβ”€β”€ external/   # Third-party Fastify plugins
β”‚           β”‚   β”‚   β”œβ”€β”€ cors.ts
β”‚           β”‚   β”‚   β”œβ”€β”€ env.ts          # Type-safe env schema
β”‚           β”‚   β”‚   β”œβ”€β”€ helmet.ts
β”‚           β”‚   β”‚   β”œβ”€β”€ multipart.ts
β”‚           β”‚   β”‚   β”œβ”€β”€ rate-limit.ts
β”‚           β”‚   β”‚   β”œβ”€β”€ sensible.ts
β”‚           β”‚   β”‚   β”œβ”€β”€ swagger.ts      # OpenAPI + Swagger UI
β”‚           β”‚   β”‚   └── under-pressure.ts
β”‚           β”‚   └── internal/   # App-specific plugins
β”‚           β”‚       β”œβ”€β”€ authentication.ts   # Better Auth plugin
β”‚           β”‚       └── db.ts               # Drizzle connection
β”‚           └── routes/
β”‚               β”œβ”€β”€ health.ts           # GET /health
β”‚               β”œβ”€β”€ root.route.ts       # Root route
β”‚               └── api/
β”‚                   β”œβ”€β”€ auth.hook.ts    # Session guard (cascades to child routes)
β”‚                   └── v1/
β”‚                       └── protected.ts    # Example protected endpoint
β”‚
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ db/                     # @fastify-forge/db β€” Drizzle client & schema
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ index.ts        # Drizzle client export
β”‚   β”‚       └── schema.ts       # users, sessions, accounts tables
β”‚   └── logger/                 # @fastify-forge/logger β€” Pino logger instance
β”‚       └── src/
β”‚           └── index.ts
β”‚
β”œβ”€β”€ cli/                        # npx fastify-forge scaffolder
β”œβ”€β”€ docker-compose.yaml         # PostgreSQL 17 service
β”œβ”€β”€ nx.json                     # Nx workspace configuration
β”œβ”€β”€ pnpm-workspace.yaml         # pnpm catalogs & workspace config
└── eslint.config.js            # ESLint 9 flat config

πŸ”Œ Plugins at a Glance

Plugins are auto-discovered from the plugins/ directory via @fastify/autoload. Adding a new plugin is as simple as dropping a file:

// apps/api/src/plugins/external/my-plugin.ts
import fp from 'fastify-plugin';
import myPlugin from 'fastify-my-plugin';

export default fp(async (fastify) => {
  await fastify.register(myPlugin, {
    /* options */
  });
});

Route hooks & authentication

The auth.hook.ts file lives next to the api/ route folder and cascades down to every child route automatically. Any route placed inside api/ is protected by session validation β€” no extra wiring needed.

routes/
└── api/
    β”œβ”€β”€ auth.hook.ts   ← runs for all routes below this directory
    └── v1/
        └── protected.ts   ← session already validated βœ“

πŸ—„οΈ Database

The @fastify-forge/db package exports a ready-to-use Drizzle ORM client and a starter schema:

  • users β€” id, email, name, role (admin | user), image, ban management, timestamps
  • sessions β€” token, expiry, user agent, IP address, impersonation support
  • accounts β€” OAuth provider accounts with access/refresh token storage

Useful database commands

# Generate a new migration
pnpm --filter @fastify-forge/db db:generate

# Push schema to database (dev)
pnpm --filter @fastify-forge/db db:push

# Open Drizzle Studio
pnpm --filter @fastify-forge/db db:studio

πŸ” Authentication

Authentication is powered by Better Auth with the following setup out of the box:

  • Email & password sign-up / sign-in
  • Session caching (5-minute cookie cache) to reduce database hits
  • Admin plugin for user management endpoints
  • OpenAPI integration β€” auth routes appear in the Swagger UI at /docs
  • 1-week session expiry with daily refresh
// Sign in β€” POST /api/auth/sign-in/email
{
  "email": "[email protected]",
  "password": "supersecret"
}

πŸ“– API Documentation

Swagger UI is served at /docs and is automatically populated from TypeBox schemas on your route definitions. Add a schema to any route and it appears instantly:

app.route({
  url: '/users/:id',
  method: 'GET',
  schema: {
    tags: ['Users'],
    params: Type.Object({ id: Type.String({ format: 'uuid' }) }),
    response: { 200: UserSchema }
  },
  handler: async (req) => getUserById(req.params.id)
});

πŸ“œ Available Scripts

Run these from the workspace root:

| Command | Description | | ---------------- | --------------------------------------------- | | pnpm start | Start all apps in parallel | | pnpm build | Build all packages and apps | | pnpm lint | Lint all projects | | pnpm typecheck | Type-check all projects | | pnpm test | Run all tests | | pnpm format | Format all files with Prettier | | pnpm clean | Remove all build artifacts and node_modules |

Nx only re-runs tasks for projects affected by your changes, keeping feedback loops fast.


πŸ› οΈ CLI Reference

npx fastify-forge [options]

| Flag | Description | | --------------- | ------------------------------------------------------------ | | --name <name> | Project name / directory (prompted interactively if omitted) | | --no-git | Skip git repository initialisation |


🀝 Contributing

Contributions are welcome! Please follow Conventional Commits for commit messages β€” the commit-lint hook will remind you.

# Fork & clone your fork
git clone https://github.com/<your-handle>/fastify-forge.git
cd fastify-forge
pnpm install

# Create a feature branch
git checkout -b feat/my-awesome-feature

# Make your changes, then open a PR πŸš€

Releases are managed via Changesets. If your PR includes a user-facing change, add a changeset:

pnpm changeset

πŸ“„ License

MIT Β© Flavio Del Grosso


⭐ Star on GitHub Β· πŸ“¦ npm Β· πŸ› Report a bug