
Security News
AGENTS.md Gains Traction as an Open Format for AI Coding Agents
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
base-nestjs-app
Advanced tools
A comprehensive NestJS application factory that provides a standardized way to create production-ready NestJS applications with Fastify, built-in health checks, logging integration, and microservice support.
This library provides a batteries-included NestJS application factory that handles the common configuration and setup needed for production applications:
npm install base-nestjs-app
# or
yarn add base-nestjs-app
# or
pnpm add base-nestjs-app
import { createApp } from 'base-nestjs-app';
import { ContextLoggingModule } from 'nestjs-context-winston';
async function bootstrap() {
const { app, start } = await createApp({
loggingModule: ContextLoggingModule.forRoot({
// logging configuration
}),
imports: [
// your application modules
],
providers: [
// global providers
],
});
// Start the application
await start();
}
bootstrap();
import { createApp } from 'base-nestjs-app';
import { ContextLoggingModule } from 'nestjs-context-winston';
async function bootstrap() {
const { app, start } = await createApp({
// Server configuration
server: {
port: 4000,
http2: true,
compression: 'max',
bodyLimitMb: 10,
maxParamLengthKb: 100,
// Enable GET request body parsing
allowGetBody: true,
},
// Logging integration
loggingModule: ContextLoggingModule.forRoot({
// your logging config
}),
// CORS configuration
cors: ['https://myapp.com', 'https://admin.myapp.com'], // Specific origins
// cors: true, // Allow all origins (default)
// cors: false, // Disable CORS
// Health check configuration
healthCheck: {
enabled: true,
healthCheckRoute: 'health',
},
// Application modules and providers
imports: [YourAppModule],
providers: [GlobalService],
// Microservice support
microservices: [
{
hybridOptions: {
// NestJS hybrid app options
},
},
],
});
await start();
}
bootstrap();
Property | Type | Default | Description |
---|---|---|---|
server | BaseNestJsServerOptions | {} | Server configuration options |
loggingModule | ContextLoggingModuleInstance | required | Logging module instance |
cors | boolean | string[] | true | CORS configuration: true for permissive, false to disable, or array of allowed origins |
imports | DynamicModule['imports'] | [] | NestJS modules to import |
providers | DynamicModule['providers'] | [] | Global providers |
microservices | MSOptions[] | [] | Microservice configurations |
healthCheck | HealthCheckOptions | { enabled: true } | Health check configuration |
Property | Type | Default | Description |
---|---|---|---|
port | number | 3000 | Server port |
http2 | boolean | false | Enable HTTP/2 support |
compression | 'none' | 'min' | 'average' | 'max' | undefined | Response compression level |
bodyLimitMb | number | 50 | Request body size limit in MB |
maxParamLengthKb | number | 65 | Maximum parameter length in KB |
allowGetBody | boolean | false | Enable body parsing for GET requests |
Property | Type | Default | Description |
---|---|---|---|
enabled | boolean | true | Enable health check endpoint |
healthCheckRoute | string | 'health-check' | Health check endpoint path |
The library automatically provides a health check endpoint that returns:
{
"status": "pass",
"version": "1",
"releaseID": "1.0.0",
"serviceID": "your-service-name"
}
Access it at: GET /health-check
(or your configured route)
Swagger documentation is automatically generated and available at /docs
with:
The library integrates with nestjs-context-winston
for structured logging:
Built-in response compression with configurable levels:
'none'
- No compression'min'
- Minimal compression (fastest)'average'
- Balanced compression'max'
- Maximum compression (smallest size)origin: true, credentials: true
)cors: false
to explicitly disable CORScors: ['https://example.com', 'https://app.example.com']
to allow specific origins onlyCreate hybrid applications that can handle both HTTP and microservice protocols:
const { app, start } = await createApp({
loggingModule: myLoggingModule,
imports: [AppModule],
microservices: [
{
hybridOptions: {
// Custom hybrid application options
},
},
],
});
Enable body parsing for GET requests (useful for complex search APIs):
const { app, start } = await createApp({
loggingModule: myLoggingModule,
imports: [AppModule],
allowGetBody: true,
});
This library includes a permissive JSON parser that handles edge cases gracefully:
{}
instead of throwing an errorContent-Type: application/json
header even when the body is emptyallowGetBody: true
is enabled, as some clients may send content-type headers with empty GET request bodiesThis behavior ensures your API remains robust and doesn't fail due to harmless client-side quirks while maintaining proper JSON parsing for valid payloads.
Customize the health check endpoint:
const { app, start } = await createApp({
loggingModule: myLoggingModule,
imports: [AppModule],
healthCheck: {
enabled: true,
healthCheckRoute: 'api/health',
},
});
Creates a configured NestJS application with Fastify.
Returns:
{
app: INestApplication;
start: () => Promise<INestApplication>;
}
app
- The configured NestJS application instancestart()
- Function to start the application and listen on the configured portThe library is written in TypeScript and provides comprehensive type definitions for all configuration options and return types.
import type {
BaseNestjsOptions,
BaseNestJsServerOptions,
HealthCheckOptions,
CompressionOptions
} from 'base-nestjs-app';
This library is part of the Codibre NestJS Context monorepo. Please see the root README for contribution guidelines.
ISC License - see LICENSE file for details.
Built with โค๏ธ by Codibre
The instrumentation module MUST be imported as the FIRST module in your main application module. This ensures proper initialization before any other application code runs.
import { Module } from '@nestjs/common';
import { NestJsNewrelicInstrumentationModule } from 'newrelic-nestjs-instrumentation';
// Import other modules AFTER the instrumentation module
import { UsersModule } from './users/users.module';
import { OrdersModule } from './orders/orders.module';
@Module({
imports: [
// โ ๏ธ CRITICAL: Must be the FIRST import
NestJsNewrelicInstrumentationModule,
// Other modules come after
UsersModule,
OrdersModule,
],
})
export class AppModule {}
Ensure you have New Relic configured in your application:
// main.ts (before importing any other modules)
import 'newrelic';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
NEW_RELIC_LICENSE_KEY=your_license_key
NEW_RELIC_APP_NAME=your_app_name
NEW_RELIC_LOG_LEVEL=info
@Controller('sqs')
export class SqsController {
constructor(private readonly sqsService: SqsService) {}
@Post('process-message')
async processMessage(@Body() sqsEvent: any) {
// New Relic transaction automatically created
// Transaction name: "SqsController.processMessage"
for (const record of sqsEvent.Records) {
await this.sqsService.processMessage(record);
}
return { processed: sqsEvent.Records.length };
}
}
@Controller('kafka')
export class KafkaController {
constructor(
private readonly kafkaService: KafkaService,
private readonly events: NewReliNestjsEvent
) {
// Monitor Kafka message processing
this.events.on('transactionStarted', (transactionId) => {
console.log(`Processing Kafka message in transaction: ${transactionId}`);
});
}
@Post('handle-message')
async handleMessage(@Body() kafkaMessage: any) {
// Automatic transaction tracking for Kafka messages
const result = await this.kafkaService.process(kafkaMessage);
// Transaction context preserved throughout processing
return result;
}
}
// Works seamlessly with HTTP/2
@Controller('users')
export class UserController {
@Get(':id')
async getUser(@Param('id') id: string) {
// Full HTTP/2 support with proper transaction tracking
// Distributed tracing headers automatically handled
return this.userService.findById(id);
}
}
@Injectable()
export class CronService {
constructor(private readonly events: NewReliNestjsEvent) {}
@Cron('0 */6 * * *') // Every 6 hours
async processScheduledTask() {
// For cron jobs, manually trigger the guard and interceptor
// or create a controller endpoint and call it internally
return this.performTask();
}
}
// Better approach for cron jobs:
@Controller('cron')
export class CronController {
@Post('scheduled-task')
async scheduledTask() {
// This will be properly instrumented
return this.cronService.performTask();
}
}
The main module that sets up New Relic instrumentation.
@Module({
imports: [NestJsNewrelicInstrumentationModule]
})
export class AppModule {}
What it provides:
NewrelicContextGuard
for transaction managementNewrelicInterceptor
for transaction lifecycleNewReliNestjsEvent
service for event monitoringEvent emitter service for monitoring transaction lifecycle.
@Injectable()
export class MyService {
constructor(private events: NewReliNestjsEvent) {
this.setupEventListeners();
}
private setupEventListeners() {
// Transaction started successfully
this.events.on('transactionStarted', (transactionId: string) => {
console.log(`Transaction ${transactionId} started`);
});
// Transaction completed (success or error)
this.events.on('transactionFinished', (transactionId: string) => {
console.log(`Transaction ${transactionId} finished`);
});
// Transaction creation failed
this.events.on('transactionStartFailed', (transactionId: string, error: unknown) => {
console.error(`Transaction ${transactionId} failed to start:`, error);
});
}
}
Guard that sets up New Relic transaction context (automatically applied globally).
Transaction Naming Convention:
ControllerName.methodName
UserController.getUser
, KafkaController.processMessage
Interceptor that manages transaction lifecycle (automatically applied globally).
@Injectable()
export class CustomMonitoringService {
private transactionMetrics = new Map<string, { startTime: number }>();
constructor(private events: NewReliNestjsEvent) {
this.setupAdvancedMonitoring();
}
private setupAdvancedMonitoring() {
this.events.on('transactionStarted', (transactionId) => {
this.transactionMetrics.set(transactionId, {
startTime: Date.now()
});
// Send to external monitoring system
this.externalMonitoring.trackTransactionStart(transactionId);
});
this.events.on('transactionFinished', (transactionId) => {
const metrics = this.transactionMetrics.get(transactionId);
if (metrics) {
const duration = Date.now() - metrics.startTime;
this.externalMonitoring.trackTransactionEnd(transactionId, duration);
this.transactionMetrics.delete(transactionId);
}
});
}
}
@Injectable()
export class ErrorTrackingService {
constructor(private events: NewReliNestjsEvent) {
this.events.on('transactionStartFailed', (transactionId, error) => {
// Log to external error tracking service
this.errorTracker.captureException(error, {
transactionId,
context: 'newrelic-transaction-start'
});
});
}
}
Always import the New Relic module early in your application:
// Correct order
@Module({
imports: [
NestJsNewrelicInstrumentationModule, // First
DatabaseModule,
AuthModule,
// Other modules...
],
})
export class AppModule {}
Use environment-specific New Relic configuration:
// config/newrelic.config.ts
export const newRelicConfig = {
development: {
enabled: false,
logging: { level: 'trace' }
},
production: {
enabled: true,
logging: { level: 'info' }
}
};
Always handle New Relic instrumentation errors gracefully:
@Injectable()
export class SafeInstrumentationService {
constructor(private events: NewReliNestjsEvent) {
this.events.on('transactionStartFailed', (transactionId, error) => {
// Log but don't throw - keep application functional
this.logger.warn(`New Relic transaction failed: ${transactionId}`, error);
});
}
}
Monitor the performance impact of instrumentation:
@Injectable()
export class PerformanceMonitoringService {
constructor(private events: NewReliNestjsEvent) {
this.events.on('transactionStarted', (transactionId) => {
// Track instrumentation overhead
this.performanceMonitor.startTimer(`instrumentation.${transactionId}`);
});
}
}
Transactions not appearing in New Relic
NEW_RELIC_LICENSE_KEY
is setHTTP/2 requests not tracked
SQS/Kafka messages not instrumented
@Post()
or similar decorators for handler methodsEvents not firing
NewReliNestjsEvent
is properly injectedEnable debug logging to troubleshoot issues:
@Injectable()
export class DebugService {
constructor(private events: NewReliNestjsEvent) {
// Log all transaction events
this.events.on('transactionStarted', (id) =>
console.log(`[DEBUG] Transaction started: ${id}`));
this.events.on('transactionFinished', (id) =>
console.log(`[DEBUG] Transaction finished: ${id}`));
this.events.on('transactionStartFailed', (id, error) =>
console.error(`[DEBUG] Transaction failed: ${id}`, error));
}
}
We welcome contributions! Please see our Contributing Guide for details on development setup, testing, and submission guidelines.
# Clone the repository
git clone https://github.com/your-org/newrelic-nestjs-instrumentation.git
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run linting
pnpm lint
# Build the project
pnpm build
This project is licensed under the ISC License - see the LICENSE file for details.
FAQs
Nestjs wrapper for creation of standarized apps
The npm package base-nestjs-app receives a total of 27 weekly downloads. As such, base-nestjs-app popularity was classified as not popular.
We found that base-nestjs-app demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.