@nextrush/dev
v3.0.6
Published
Development server and build tools for NextRush - multi-runtime support
Maintainers
Readme
@nextrush/dev
Development server and build tools for NextRush with multi-runtime support.
Quick Start
# Install
pnpm add -D @nextrush/dev
# Start development server (auto-detects everything)
nextrush dev
# Build for production
nextrush buildThat's it! No configuration needed. The CLI auto-detects:
- Entry file (
src/index.ts,src/main.ts, etc.) - Runtime (Node.js, Bun, or Deno)
- TypeScript settings from
tsconfig.json
The Problem
TypeScript decorators with dependency injection require emitDecoratorMetadata to work. This compiler option emits type information at runtime:
// This TypeScript:
@Controller('/users')
class UserController {
constructor(private userService: UserService) {}
}
// Needs to emit this metadata:
Reflect.metadata('design:paramtypes', [UserService]);Without this metadata, the DI container cannot resolve constructor parameters:
TypeInfo not known for UserControllerThe Problem with Modern Bundlers
Most modern bundlers strip types without emitting decorator metadata:
| Tool | Speed | Decorator Metadata | DI Works? |
| -------------------- | ------------- | ------------------ | --------- |
| tsup / esbuild | ⚡ Fast | ❌ Not emitted | ❌ No |
| tsx | ⚡ Fast | ❌ Not emitted | ❌ No |
| node --strip-types | ⚡ Fast | ❌ Not emitted | ❌ No |
| tsc | 🐢 Build step | ✅ Emitted | ✅ Yes |
| nextrush dev | ⚡ Fast | ✅ Emitted | ✅ Yes |
| nextrush build | ⚡ Fast | ✅ Emitted | ✅ Yes |
Installation
pnpm add -D @nextrush/devCommands
nextrush dev - Development Server
Start a development server with hot reload and decorator support.
# Auto-detects entry file
nextrush dev
# Specify entry file
nextrush dev ./src/server.ts
# Custom port
nextrush dev --port 4000
# Enable debugger
nextrush dev --inspectOptions:
| Option | Alias | Default | Description |
| ---------------- | ----- | ------- | --------------------------- |
| --port | -p | 3000 | Port number |
| --watch | -w | src | Paths to watch (repeatable) |
| --inspect | - | false | Enable Node.js inspector |
| --inspect-port | - | 9229 | Inspector port |
| --no-clear | - | - | Don't clear screen on start |
| --verbose | -v | false | Verbose output |
nextrush build - Production Build
Build for production with SWC, emitting decorator metadata.
# Build with defaults
nextrush build
# Custom output directory
nextrush build --outDir dist
# Minify output
nextrush build --minify
# Target ES2020
nextrush build --target es2020Options:
| Option | Alias | Default | Description |
| ------------------------- | ----- | -------- | ---------------------------- |
| --outDir | -o | dist | Output directory |
| --target | -t | es2022 | Target ES version |
| --sourcemap | - | true | Generate sourcemaps |
| --no-sourcemap | - | - | Disable sourcemaps |
| --minify | -m | false | Minify output |
| --no-decorator-metadata | - | - | Skip decorator metadata |
| --no-clean | - | - | Don't clean output directory |
| --verbose | -v | false | Verbose output |
nextrush generate - Code Generator
Generate controllers, services, middleware, guards, and routes.
# Generate a controller class
nextrush generate controller user
# Short alias
nextrush g controller user
# Generate all types
nextrush g s user-profile # Service
nextrush g mw logger # Middleware
nextrush g guard auth # Guard
nextrush g r products # RouteTypes:
| Type | Alias | Output Path | Style |
| ------------ | ----- | -------------------------------------- | ----------- |
| controller | c | src/controllers/<name>.controller.ts | Class-based |
| service | s | src/services/<name>.service.ts | Class-based |
| middleware | mw | src/middleware/<name>.ts | Functional |
| guard | g | src/guards/<name>.guard.ts | Functional |
| route | r | src/routes/<name>.ts | Functional |
Generated Controller Example:
// nextrush g controller user → src/controllers/user.controller.ts
import { Controller, Get, Post, Body, Param } from 'nextrush';
@Controller('/user')
export class UserController {
@Get()
async findAll() {
return [];
}
@Get('/:id')
async findOne(@Param('id') id: string) {
return { id };
}
@Post()
async create(@Body() data: unknown) {
return data;
}
}Generated Service Example:
// nextrush g s order → src/services/order.service.ts
import { Service } from 'nextrush';
@Service()
export class OrderService {
async findAll() {
return [];
}
async findOne(id: string) {
return { id };
}
async create(data: unknown) {
return data;
}
}Naming Rules:
- Use lowercase letters, numbers, and hyphens:
user,user-profile,v2 - Multi-word names are converted to PascalCase:
user-profile→UserProfileController - Duplicate file detection: won't overwrite existing files
Package.json Scripts
{
"scripts": {
"dev": "nextrush dev",
"build": "nextrush build",
"start": "node dist/index.js",
"generate": "nextrush generate"
}
}Multi-Runtime Support
The CLI automatically detects and adapts to your runtime environment:
| Runtime | Dev Server | Production Build | Decorator Metadata |
| ----------- | ----------------------- | ----------------- | ------------------ |
| Node.js | ✅ @swc-node/register | ✅ @swc/core | ✅ Full support |
| Bun | ✅ Native --watch | ✅ Native bundler | ✅ Full support |
| Deno | ✅ Native --watch | ✅ npm:@swc/core | ✅ Full support |
How It Works
Node.js:
- Dev: Uses
@swc-node/registerfor SWC-powered TypeScript execution with decorator metadata - Build: Uses
@swc/coretransform API withdecoratorMetadata: true
Bun:
- Dev: Native TypeScript execution with
bun --watch - Build: Native
Bun.build()bundler (preserves decorator metadata!)
Deno:
- Dev: Native TypeScript execution with
deno run --watch - Build: Uses
npm:@swc/corefor consistent decorator metadata emission
Runtime Detection
import { detectRuntime, getRuntimeInfo } from '@nextrush/dev';
const runtime = detectRuntime(); // 'node' | 'bun' | 'deno'
const info = getRuntimeInfo();
// {
// runtime: 'node',
// version: '22.0.0',
// supportsTypeScript: false,
// supportsWatch: true,
// needsSwc: true
// }Programmatic API (Optional)
Note: The programmatic API is optional. Most users only need the CLI commands (
nextrush devandnextrush build), which auto-detect everything.
The programmatic API is useful for:
- Build tool integration
- Custom build scripts
- Monorepo setups
- Testing frameworks
dev(entry?, options?): Promise<SpawnResult>
Start the development server programmatically.
import { dev } from '@nextrush/dev';
// Simple - auto-detect entry
await dev();
// With entry file
await dev('./src/app.ts');
// With options
await dev('./src/app.ts', {
port: 4000,
inspect: true,
watch: ['./src', './config'],
env: { DATABASE_URL: 'postgres://...' },
});DevOptions:
| Option | Type | Default | Description |
| ------------- | ------------------------ | --------- | --------------------- |
| entry | string | auto | Entry file path |
| port | number | 3000 | Port number |
| inspect | boolean | false | Enable debugger |
| inspectPort | number | 9229 | Debugger port |
| watch | string[] | ['src'] | Watch paths |
| env | Record<string, string> | {} | Environment variables |
| clearScreen | boolean | true | Clear screen on start |
| verbose | boolean | false | Verbose output |
build(entry?, options?): Promise<void>
Build for production programmatically.
import { build } from '@nextrush/dev';
// Simple
await build();
// With options
await build('./src/index.ts', {
outDir: 'dist',
minify: true,
sourcemap: true,
target: 'es2022',
});BuildOptions:
| Option | Type | Default | Description |
| ------------------- | --------- | ---------- | ----------------------- |
| entry | string | auto | Entry file path |
| outDir | string | 'dist' | Output directory |
| target | string | 'es2022' | ES target |
| sourcemap | boolean | true | Generate sourcemaps |
| minify | boolean | false | Minify output |
| decoratorMetadata | boolean | true | Emit decorator metadata |
| clean | boolean | true | Clean output first |
| verbose | boolean | false | Verbose output |
Auto-Detection
Entry file detection order:
package.jsonmainormodulefield (convertsdist/tosrc/,.jsto.ts)src/index.tssrc/main.tssrc/app.tssrc/server.tsindex.tsmain.tsapp.tsserver.ts
Requirements
- Node.js >= 22.0.0 (for native
--watchsupport) tsconfig.jsonwith:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}Why Not Use tsup/esbuild?
tl;dr: They don't emit decorator metadata, breaking DI.
// Your code
@Service()
class UserService {
constructor(private db: Database) {}
}
// After tsup/esbuild (metadata LOST):
let UserService = class {
constructor(db) {}
};
// After nextrush build (metadata PRESERVED):
let UserService = class {
constructor(db) {}
};
Reflect.defineMetadata('design:paramtypes', [Database], UserService);The nextrush build command uses SWC with decoratorMetadata: true, which properly emits the reflection metadata required by tsyringe and other DI containers.
API Reference
Runtime Detection
import {
detectRuntime, // () => 'node' | 'bun' | 'deno'
getRuntimeInfo, // () => RuntimeInfo
isNode, // () => boolean
isBun, // () => boolean
isDeno, // () => boolean
} from '@nextrush/dev';Configuration
import {
findEntry, // () => string
loadConfig, // () => Promise<NextRushConfig>
getDefaultWatchPaths, // () => string[]
} from '@nextrush/dev';Code Generation
import {
generate, // (type, name, cwd?) => Promise<string>
generateCli, // (args: string[]) => Promise<void>
GENERATOR_TYPES, // ['controller', 'service', 'middleware', 'guard', 'route']
} from '@nextrush/dev';
// Programmatic usage
const filePath = await generate('controller', 'user', process.cwd());Production Readiness
Current Status: Beta
This package is functional and tested across all major runtimes:
| Feature | Status | Notes | | ------------- | --------- | ----------------------- | | Node.js dev | ✅ Stable | Full support | | Node.js build | ✅ Stable | Full decorator metadata | | Bun dev | ✅ Stable | Native support | | Bun build | ✅ Stable | Full decorator metadata | | Deno dev | ✅ Stable | Native support | | Deno build | ✅ Stable | Uses npm:@swc/core | | Generate | ✅ Stable | All 5 generator types |
All Runtimes Support Decorator Metadata
All three runtimes (nextrush build) now properly emit decorator metadata:
- Node.js: @swc/core transform API
- Bun: Native bundler preserves metadata
- Deno: npm:@swc/core via npm specifier
Architecture Documentation
For a deep dive into how this package works, see ARCHITECTURE.md.
License
MIT © NextRush Team
