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

@kayouris/nestjs-maintenance

v1.0.0

Published

A NestJS dynamic module for maintenance mode management

Readme

NestJS Maintenance Mode Module

NPM Version Build Status Coverage License: MIT Powered by Bun

A lightweight, zero-config NestJS dynamic module that gracefully puts your API into maintenance mode with a single line of code. When active, it automatically intercepts every incoming request and returns an HTTP 503 Service Unavailable response — without touching a single controller. Specific routes or entire controllers can be exempted via the @BypassMaintenance() decorator, and the state can be toggled at runtime with no restart required.


✨ Features

  • 🧠 In-memory state management — no database or external service required
  • 🔄 Sync & Async module registration — forRoot() and forRootAsync() with full factory/class/useExisting support
  • 🌍 Global guard auto-registration — registered via APP_GUARD so it covers every route automatically
  • 🏷️ @BypassMaintenance() decorator — opt-out at the method or controller level with a single decorator
  • ⚡ Ultra-fast — built and tested with Bun
  • ✅ 100% test coverage — unit and integration tests with bun:test and @nestjs/testing
  • 🤝 NestJS 10 & 11 compatible via peer dependencies

📦 Installation

# Bun (recommended)
bun add @kayouris/nestjs-maintenance

# NPM
npm install @kayouris/nestjs-maintenance

# Yarn
yarn add @kayouris/nestjs-maintenance

Peer dependencies — ensure these are installed in your project: @nestjs/common, @nestjs/core, rxjs


🚀 Quick Start

Synchronous registration

// app.module.ts
import { Module } from '@nestjs/common';
import { MaintenanceModule } from '@kayouris/nestjs-maintenance';

@Module({
  imports: [
    MaintenanceModule.forRoot({
      enabledInitially: false, // start with maintenance OFF
    }),
  ],
})
export class AppModule {}

Asynchronous registration

Ideal when the initial state comes from an environment variable or external config service:

// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MaintenanceModule } from '@kayouris/nestjs-maintenance';

@Module({
  imports: [
    ConfigModule.forRoot(),
    MaintenanceModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => ({
        enabledInitially: config.get<boolean>('MAINTENANCE_MODE', false),
      }),
      inject: [ConfigService],
    }),
  ],
})
export class AppModule {}

Bypassing maintenance on specific routes

Use @BypassMaintenance() on a single handler or an entire controller class to exempt it from the guard:

// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { BypassMaintenance } from '@kayouris/nestjs-maintenance';

@Controller()
export class AppController {

  // ✅ Always reachable — even when maintenance is ON
  @BypassMaintenance()
  @Get('health')
  healthCheck() {
    return { status: 'ok' };
  }

  // 🔒 Returns HTTP 503 when maintenance is active
  @Get('products')
  getProducts() {
    return [];
  }
}

// You can also exempt an entire controller:
@BypassMaintenance()
@Controller('admin')
export class AdminController { /* all routes bypass maintenance */ }

🔧 Dynamic Toggling

Inject MaintenanceService anywhere in your application to control maintenance mode programmatically at runtime — no restart needed:

// admin.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { BypassMaintenance, MaintenanceService } from '@kayouris/nestjs-maintenance';

@BypassMaintenance() // admin routes must remain accessible during maintenance
@Controller('admin/maintenance')
export class AdminController {
  constructor(private readonly maintenanceService: MaintenanceService) {}

  @Post('enable')
  enable() {
    this.maintenanceService.setMaintenanceMode(true);
    return { maintenanceActive: true };
  }

  @Post('disable')
  disable() {
    this.maintenanceService.setMaintenanceMode(false);
    return { maintenanceActive: false };
  }

  @Post('toggle')
  toggle() {
    const newState = this.maintenanceService.toggleMaintenanceMode();
    return { maintenanceActive: newState };
  }

  @Get('status')
  status() {
    return { maintenanceActive: this.maintenanceService.isMaintenanceEnabled() };
  }
}

MaintenanceService API

| Method | Return | Description | |---|---|---| | setMaintenanceMode(enabled: boolean) | void | Explicitly enable or disable maintenance mode | | isMaintenanceEnabled() | boolean | Returns the current maintenance state | | toggleMaintenanceMode() | boolean | Flips the state and returns the new value |


🧪 Local Example

A fully working demo application lives in the example/ directory. It exposes three endpoints to let you observe the guard in action:

| Method | Route | Behaviour | |---|---|---| | GET | /public | @BypassMaintenance() — always returns 200 | | GET | /secure | Returns 503 when maintenance is ON | | POST | /maintenance/toggle | Flips maintenance mode ON / OFF |

Run it locally:

# 1. Build the library from the repo root
bun run build

# 2. Install example dependencies and start the server
cd example
bun install
bun run start

The server will start on http://localhost:3000. You can then exercise it with curl:

# Secure endpoint is accessible (maintenance OFF)
curl http://localhost:3000/secure

# Enable maintenance
curl -X POST http://localhost:3000/maintenance/toggle

# Secure endpoint is now blocked (503)
curl http://localhost:3000/secure

# Public route always passes through
curl http://localhost:3000/public

# Disable maintenance
curl -X POST http://localhost:3000/maintenance/toggle

📄 License

Distributed under the MIT License. See LICENSE for details.