Common utilities for building NestJS backends. Provides reusable modules, configuration presets, and helpers extracted from production projects.
pnpm add @fullstackhouse/nestjs-commonAll dependencies are optional peers — install only what you use.
Environment — /env
Helpers for reading environment variables with type safety.
Parses string env vars into booleans. Returns true for '1'/'true', false for '0'/'false', and undefined for anything else.
import { parseBoolean } from '@fullstackhouse/nestjs-common/env';
export const sentryEnabled = parseBoolean(process.env.SENTRY_ENABLED) ?? true;
export const cli = parseBoolean(process.env.CLI) ?? false;Returns process.env.APP_ENV, defaulting to 'prod'. Used internally by other modules (e.g. logging) to toggle behavior.
Returns true when APP_ENV === 'local'.
HTTP — /http
HTTP request helpers.
Extracts the client IP address from an Express request. Reads the first IP from the x-forwarded-for header (for reverse proxies / load balancers), falling back to req.socket.remoteAddress.
import { getRequestClientIp } from '@fullstackhouse/nestjs-common/http';
const ip = getRequestClientIp(req);Sentry — /sentry
Sentry error tracking integration for NestJS. Requires @sentry/nestjs and @sentry/profiling-node as peer deps.
Wraps Sentry.init() with production-friendly defaults:
tracesSampleRate: 0.1,profilesSampleRate: 0.1- Node.js profiling integration
- 4xx filter (enabled by default): prevents
HttpExceptionwith 4xx status codes from being reported to Sentry. Disable withfilter4xx: false.
Any standard Sentry.init() options can be passed through. If you provide a custom beforeSend, it runs after the 4xx filter.
// sentry.ts — import at the top of main.ts
import { initSentry } from '@fullstackhouse/nestjs-common/sentry';
initSentry({
enabled: sentryEnabled,
dsn: sentryDsn,
environment: appEnv,
});All-in-one module that registers both SentryModule (instrumentation) and SentryExceptionFilter (global exception capture). This is the recommended way to set up Sentry:
import { CommonSentryModule } from '@fullstackhouse/nestjs-common/sentry';
@Module({
imports: [CommonSentryModule.forRoot()],
})
export class AppModule {}Global exception filter that captures all exceptions to Sentry, then delegates to NestJS's default error handling. Included automatically by CommonSentryModule — only use directly if you need custom provider registration.
Re-exported from @sentry/nestjs/setup. Registers Sentry instrumentation in the NestJS dependency injection system. Included automatically by CommonSentryModule.
Logging — /logging
Pino-based structured logging for NestJS. Requires nestjs-pino and pino-http as peer deps.
NestJS dynamic module that configures nestjs-pino with sensible defaults:
- Log level: reads
process.env.LOG_LEVEL, defaults to'info' - Pretty printing: enabled automatically when
APP_ENV === 'local'(usespino-prettywith single-line output and hiddenpid/hostname) - Ignored paths: suppresses access logs for
/healthby default (configurable viaignorePaths)
Options:
| Option | Type | Default | Description |
|---|---|---|---|
level |
string |
process.env.LOG_LEVEL ?? 'info' |
Pino log level |
ignorePaths |
string[] |
['/health'] |
URL paths to exclude from access logs |
import { CommonLoggerModule } from '@fullstackhouse/nestjs-common/logging';
@Module({
imports: [CommonLoggerModule.forRoot()],
})
export class AppModule {}CLS — /cls
Continuation Local Storage configuration. Requires nestjs-cls as peer dep.
Returns a base configuration object for ClsModule. Currently returns an empty config — extend it in your app as needed.
Validation — /validation
Global Zod-based validation. Requires nestjs-zod and @nestjs/common as peer deps.
Registers ZodValidationPipe from nestjs-zod as a global pipe. Call in main.ts before app.listen().
import { setupValidation } from '@fullstackhouse/nestjs-common/validation';
const app = await NestFactory.create(AppModule);
setupValidation(app);
await app.listen(3000);Swagger Metadata — /swagger
Generates NestJS Swagger plugin metadata for OpenAPI spec generation. Requires @nestjs/cli and @nestjs/swagger as peer deps.
Runs the @nestjs/swagger ReadonlyVisitor plugin to generate a metadata.ts file in your src/ directory. This file is needed for OpenAPI spec generation with the NestJS CLI plugin.
Options:
| Option | Type | Description |
|---|---|---|
rootDir |
string |
Absolute path to your app root (where src/ lives) |
// scripts/generate-metadata.ts
import { generateMetadata } from '@fullstackhouse/nestjs-common/swagger';
import { join } from 'path';
generateMetadata({ rootDir: join(__dirname, '..') });Database — /database
MikroORM + PostgreSQL configuration helpers. Requires @mikro-orm/core, @mikro-orm/postgresql, @mikro-orm/migrations, and debug as peer deps.
Builds the connection portion of a MikroORM config. Supports multiple connection strategies:
| Strategy | When | Behavior |
|---|---|---|
SKIP_DB_CONNECTION=true env var |
CI/build without a DB | Returns { connect: false } |
databaseUrl with ?host= query param |
GCP Cloud SQL Unix sockets | Extracts socket path, user, password, dbName from URL |
databaseUrl (standard) |
Standard connection strings | Returns { clientUrl, schema } |
| Individual fields | Local development | Uses host/port/user/password/dbName with defaults (localhost:5432, user postgres, db app) |
interface DatabaseConnectionOptions {
databaseUrl?: string;
host?: string;
port?: number;
user?: string;
password?: string;
dbName?: string;
schema?: string;
}Builds a complete MikroORM config on top of createDatabaseConnectionConfig. Adds:
- Entity discovery: globs for
./dist/database/entities/**/*.jsand./src/database/entities/**/*.ts(overridable) UnderscoreNamingStrategy: automatic camelCase to snake_case column mapping- Migrator extension with configurable paths (defaults:
./dist/database/migrations,./src/database/migrations) - Debug logging: enabled when the
mikro-ormdebug namespace is active (DEBUG=mikro-orm) allowGlobalContext: enabled whenCLI=trueenv var is set (for migration scripts)
interface DatabaseConfigOptions extends DatabaseConnectionOptions {
entitiesPath?: string; // default: './dist/database/entities'
entitiesTsPath?: string; // default: './src/database/entities'
migrationsPath?: string; // default: './dist/database/migrations'
migrationsTsPath?: string; // default: './src/database/migrations'
}// mikro-orm.config.ts
import { createDatabaseConfig } from '@fullstackhouse/nestjs-common/database';
import { defineConfig } from '@mikro-orm/postgresql';
export default defineConfig(
createDatabaseConfig({
databaseUrl,
host: dbHost,
port: dbPort,
user: dbUser,
password: dbPassword,
dbName,
schema: dbSchema,
}),
);Migrations — /database/migrate
CLI migration runner for MikroORM. Requires @mikro-orm/core and @mikro-orm/postgresql as peer deps.
Parses CLI arguments for migration scripts. Defaults to process.argv.
Supported flags:
| Flag | Description |
|---|---|
up / down |
Migration direction (positional, required) |
--disable-custom-schema |
Don't set search_path before migrating |
-t / --to <version> |
Migrate to a specific version |
-f / --from <version> |
Migrate from a specific version |
-o / --only <versions> |
Run only specific migrations (comma or space separated) |
-h / --help |
Print usage and exit |
Initializes MikroORM, then runs migrator.up() or migrator.down() inside a transaction. If the config uses a custom schema (not public), it sets search_path on the connection before migrating (disable with --disable-custom-schema). Exits the process with code 0 on success, 1 on failure.
// migrate.ts
import { parseMigrateArgs, runMigrations } from '@fullstackhouse/nestjs-common/database/migrate';
import config from './mikro-orm.config';
void runMigrations(config, parseMigrateArgs());Usage: ts-node src/database/migrate.ts up / ts-node src/database/migrate.ts down --to 20240101
Testing Setup — /testing/setup
Side-effect import that loads dotenv and reflect-metadata. Use as a Vitest setupFiles entry to ensure env vars and decorator metadata are available before tests.
// test/setup.ts
import '@fullstackhouse/nestjs-common/testing/setup';Vitest — /config/vitest
Creates a Vitest config with production-tested defaults:
- SWC plugin for fast TypeScript compilation (ES6 module output)
- Globals enabled (
describe,it,expectwithout imports) - GitHub Actions reporter added automatically in CI
- better-auth noise filter: suppresses
SERVER_ERRORconsole logs from better-auth during tests - Thread pool with
fileParallelism: falseandisolate: falsefor speed - Excludes
node_modulesanddist
Override any test options or add Vite plugins:
// vitest.config.ts
import { createVitestConfig } from '@fullstackhouse/nestjs-common/config/vitest';
export default createVitestConfig({
test: { setupFiles: ['./test/setup.ts'] },
});ESLint — /config/eslint
Creates an ESLint flat config with:
typescript-eslintrecommended + type-checked + stylistic rulesprettierintegration viaeslint-plugin-prettier- Custom rules:
curly: 'all',array-type: 'array-simple',return-await: 'always', no absolutesrc/imports - Relaxed rules for migrations (
require-await: off), controllers/DTOs (no-unsafe-call: off), and test files (multipleno-unsafe-*: off)
Options:
| Option | Type | Default | Description |
|---|---|---|---|
rootDir |
string |
(required) | Absolute path to the project root |
tsconfigPath |
string |
'./tsconfig.lint.json' |
Path to the tsconfig for type-checked linting |
// eslint.config.mjs
import { createEslintConfig } from '@fullstackhouse/nestjs-common/config/eslint';
export default createEslintConfig({
rootDir: import.meta.dirname,
});Requires peer deps: eslint, typescript-eslint, @eslint/eslintrc, @eslint/js, eslint-config-prettier, eslint-plugin-prettier, globals.
JSON config files that can be referenced directly or copied into your project:
| Import path | Description |
|---|---|
/config/tsconfig.json |
Base TypeScript config: ES2021 target, CommonJS, decorators, source maps, skipLibCheck |
/config/tsconfig.build.json |
Extends base tsconfig, excludes node_modules, dist, and test files |
/config/nest-cli.json |
NestJS CLI config: SWC builder with type checking, @nestjs/swagger plugin with comment introspection |
/config/swcrc.json |
SWC config: TypeScript with decorator support, source maps, no minification |
/config/prettierrc.json |
Prettier config: single quotes, trailing commas |
MIT