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

nodets-boilerplate-aviato

v1.0.3

Published

Production-ready Node.js + TypeScript boilerplate with Clean Architecture

Downloads

46

Readme

Enterprise Node.js + TypeScript Boilerplate

"The universe tends toward disorder. This boilerplate is the act of building walls against entropy."

A production-ready, enterprise-grade Node.js + TypeScript starter kit implementing Clean/Hexagonal Architecture principles with strict type safety, robust error handling, and modern testing practices.

✨ Features

  • 🏗️ Clean Architecture - Strict layer separation (Domain → Application → Infrastructure → Presentation)
  • 📦 Strict TypeScript - Zero tolerance for any, strict null checks, and maximum type safety
  • ✅ Zod Validation - Runtime validation with inferred types (no duplication)
  • 📄 Cursor Pagination - Bi-directional, type-safe cursor pagination utility
  • 🎯 Result Monad - Functional error handling without exceptions
  • 🔌 Dependency Injection - Simple, type-safe DI container
  • 📝 Structured Logging - Pino-based logging with pretty dev output
  • 🧪 Vitest Testing - Unit and integration test setup with factories
  • 🗄️ Prisma ORM - Type-safe database access with repository pattern
  • 🔌 WebSockets - Real-time communication with Socket.io

🚀 Quick Start

New to the team? Start by checking DEVELOPERS.md for a day-to-day guide on adding features, debugging, and testing.

Using the CLI (Recommended)

# Initialize a new project
npx nodets-boilerplate-aviato my-new-app

Manual Setup

# Install dependencies
npm install

# Copy environment file
cp .env.example .env

# Generate Prisma client
npm run db:generate

# Start development server
npm run dev

📁 Project Structure

src/
├── domain/                    # Enterprise Business Rules (innermost)
│   ├── entities/              # Core business objects
│   ├── value-objects/         # Immutable domain primitives
│   ├── repositories/          # Repository interfaces (ports)
│   ├── errors/                # Domain-specific errors
│   └── events/                # Domain event definitions
│
├── application/               # Application Business Rules
│   ├── use-cases/             # Application services
│   ├── dtos/                  # Data Transfer Objects (validated)
│   ├── ports/                 # Secondary ports (external services)
│   └── errors/                # Application errors
│
├── infrastructure/            # Frameworks & Drivers
│   ├── database/              # Database implementations
│   ├── config/                # Configuration loading
│   ├── logging/               # Logging implementation
│   └── container/             # Dependency injection
│
├── presentation/              # Interface Adapters
│   ├── http/                  # HTTP layer (Express)
│   └── mappers/               # Entity <-> DTO mappers
│
├── shared/                    # Cross-cutting concerns
│   ├── utils/                 # Utilities (pagination, result)
│   └── types/                 # Shared type definitions
│
└── main.ts                    # Application entry point

🎯 Key Concepts

Cursor Pagination

import { CursorPaginator, createIdPaginator } from '@shared/utils/cursor-pagination.util';

// Create a paginator
const paginator = createIdPaginator<User>();

// Build paginated result (entities should have limit + 1 items)
const result = paginator.buildResult(users, { limit: 20, cursor });

// Response includes:
// - data: User[]
// - pagination: { nextCursor, prevCursor, hasNextPage, hasPrevPage, count }

Result Monad

import { ok, err, isOk, map, andThen, type Result } from '@shared/utils/result';

// Return explicit success/failure
function divide(a: number, b: number): Result<number, string> {
  return b === 0 ? err('division by zero') : ok(a / b);
}

// Chain operations
const result = andThen(
  divide(10, 2),
  (x) => divide(x, 2)
);

// Handle result
if (isOk(result)) {
  console.log(result.value); // 2.5
}

Zod Validation

import { z } from 'zod';

// Define schema once, infer type automatically
const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

// Type is inferred - no duplication!
type CreateUserDto = z.infer<typeof createUserSchema>;

// Use with validation middleware
router.post('/users', validate({ body: createUserSchema }), controller);

Error Handling

// Domain errors (business rule violations)
throw new EntityNotFoundError('User', userId);

// Application errors (HTTP-aware)
throw new UnauthorizedError('Invalid token');

// All errors are caught by global error handler:
// - Logged with full details for developers
// - Sanitized for client response

🧪 Testing

# Run all tests
npm run test

# Watch mode
npm run test:watch

# With coverage
npm run test:coverage

Test Factories

import { userFactory, traits } from 'tests/factories/entity.factory';

// Create a user with defaults
const user = userFactory.build();

// Override specific fields
const admin = userFactory.build({ name: 'Admin User' });

// Create multiple
const users = userFactory.buildMany(10);

// Apply traits
const deletedUser = traits.deleted(userFactory.build());

📜 Scripts

| Script | Description | |--------|-------------| | npm run dev | Start development server with hot reload | | npm run build | Build for production | | npm start | Start production server | | npm run typecheck | Check TypeScript types | | npm run test | Run tests | | npm run test:coverage | Run tests with coverage | | npm run db:generate | Generate Prisma client | | npm run db:migrate | Run database migrations | | npm run db:push | Push schema to database |

🔧 Configuration

Environment variables are validated at startup using Zod. See .env.example for all available options:

# Application
NODE_ENV=development
PORT=3000

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/dbname"
DB_TYPE="postgres" # postgres | mysql | mongo | firestore

# Firebase (Only if DB_TYPE=firestore)
FIREBASE_PROJECT_ID="your-project-id"
FIREBASE_CLIENT_EMAIL="[email protected]"
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."

# Security
JWT_SECRET=your-secret-key-min-32-chars

# Pagination
DEFAULT_PAGE_SIZE=20
MAX_PAGE_SIZE=100

🏛️ Architecture Philosophy

Want a deep dive? Read the Architecture Guide for a detailed breakdown perfect for onboarding new team members.

Clean Architecture

Dependencies flow inward. The domain layer knows nothing about HTTP, databases, or frameworks. This makes the core business logic:

  • Testable - No mocking of external systems needed
  • Maintainable - Changes to infrastructure don't affect domain
  • Portable - Swap Express for Fastify without touching business logic

Type Safety

TypeScript's compile-time guarantees are enhanced with:

  • Strict mode - No implicit any, strict null checks
  • Zod runtime validation - Types and validation in one place
  • Branded types - Nominal typing for IDs to prevent mixing

Error Handling

  • Domain errors - Business rule violations (e.g., EntityNotFoundError)
  • Application errors - Use case failures (e.g., UnauthorizedError)
  • Result monad - Explicit success/failure without exceptions

📄 License

MIT