Files
Ciprian Spiridon 20ba897824 Node.js v1.0.0 — new megaskill: TypeScript-first backend with Bun support, 20 reference files
Covers: HTTP servers (Express/Fastify/Hono), API design, Zod validation, Prisma/Drizzle,
auth (JWT/OAuth2), pino logging, async patterns, security, Redis caching, BullMQ queues,
testing (vitest/jest/bun test), Docker, OpenTelemetry, WebSockets, CLI tools, config.
Bun-native APIs documented as runtime variant via stack.md detection.
2026-04-01 07:20:37 +04:00

3.2 KiB

Stack — Locked Decisions & Toolchain

Every other reference file assumes these decisions. Do not deviate.

Runtime

Decision Default Notes
Runtime Node.js 22 LTS Or Bun 1.x — check bun.lockb / bunfig.toml
Language TypeScript 5.x strict noUncheckedIndexedAccess, noImplicitReturns, exactOptionalPropertyTypes
Module system ESM ("type": "module") CommonJS only for legacy compatibility layers
Package manager pnpm Or npm/yarn/bun — check lockfile

TypeScript — tsconfig.json strict settings

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "bundler",
    "module": "esnext",
    "target": "es2022",
    "outDir": "dist",
    "rootDir": "src",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

noUncheckedIndexedAccess is non-negotiable. Without it, obj[key] appears as T instead of T | undefined, hiding real bugs.

Framework

Framework When
Express 5 Established projects, large middleware ecosystem
Fastify 5 Performance-critical APIs, schema-based validation
Hono Edge-first, Bun-native, lightweight APIs
None CLI tools, workers, scripts

Detect from package.json dependencies. If unclear, ask.

Database

ORM/Query Builder When
Prisma Type-safe ORM, schema-first, migrations
Drizzle Lightweight, SQL-close, good for edge/Bun
Knex Query builder only, existing projects
None CLI tools, stateless services

Key Dependencies

Category Default Alternative
Validation Zod AJV (for JSON Schema compat)
Logging pino winston (legacy projects only)
Testing vitest jest (legacy), bun test (Bun runtime)
HTTP testing supertest undici fetch
Queues BullMQ + Redis None for simple services
Caching Redis (ioredis) In-memory LRU for single-instance
Auth jose (JWT), passport Framework-specific auth plugins
CLI commander yargs, citty
Config dotenv + Zod @nestjs/config for Nest projects

Build validation pipeline

# 1. Lint
npx eslint .

# 2. Typecheck
npx tsc --noEmit

# 3. Test
npx vitest run        # or: bun test

# 4. Build (if applicable)
npx tsc               # or: bun build ./src/index.ts --outdir ./dist

Never

  • No any — use unknown and narrow with type guards or Zod.
  • No as assertions — unless justified with a // REASON: comment.
  • No console.log in production — use pino. Lint rule: flag console.log as error.
  • No CommonJS require() — use ESM import. Exception: legacy deps that don't support ESM.
  • No synchronous file I/O in server code — use fs/promises or Bun equivalents.
  • No eval() or new Function() — ever.
  • No hardcoded secrets — env vars validated at startup.