Code Generators
Scaffold modules, controllers, services, middleware, guards, and routes from the command line
The nextrush generate command (alias nextrush g) creates new files from templates with the correct structure, imports, and naming conventions — matching the layouts the create-nextrush scaffolds emit.
Usage
nextrush generate <type> <name>
nextrush g <type> <name>Generator Types
Available generators
| Property | Type | Description |
|---|---|---|
module (m) | string | Class-based feature module with @Module, controllers, and providers |
controller (c) | string | Class-based controller with @Controller, @Get, @Post, @Param, @Body, constructor DI |
service (s) | string | Injectable service class with @Service decorator and HttpError paths |
middleware (mw) | string | Async middleware function with timing pattern |
guard (g) | string | Guard function with authorization token check pattern |
route (r) | string | Functional router (named export) with GET, GET/:id, and POST routes |
Examples
Generate a Module
nextrush g module todosCreates src/modules/todos/todos.module.ts:
import { Module } from 'nextrush/class';
import { TodosController } from './todos.controller.js';
import { TodosService } from './todos.service.js';
@Module({
controllers: [TodosController],
providers: [TodosService],
})
export class TodosModule {}A feature module composes its controller and service. Generate all three for a complete feature:
nextrush g m todos
nextrush g controller todos
nextrush g service todosThen register the module in your root module's imports.
Generate a Controller
nextrush g controller userIn a class-based project (one with a src/modules/ directory) the controller is placed
inside its feature module: src/modules/user/user.controller.ts. In a module-less project
it lands at src/controllers/user.controller.ts.
import { Body, Controller, Get, Param, Post } from 'nextrush/class';
import { UserService } from './user.service.js';
@Controller('/user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
findAll() {
return this.userService.findAll();
}
@Get('/:id')
findOne(@Param('id') id: string) {
return this.userService.findOne(id);
}
@Post()
create(@Body() data: unknown) {
return this.userService.create(data);
}
}Generate a Service
nextrush g service userCreates src/modules/user/user.service.ts in a module project, or
src/services/user.service.ts otherwise:
import { HttpError } from 'nextrush';
import { Service } from 'nextrush/class';
@Service()
export class UserService {
findAll() {
return [];
}
findOne(id: string) {
if (!id) throw new HttpError(404, 'Not found');
return { id };
}
create(data: unknown) {
if (!data || typeof data !== 'object') throw new HttpError(400, 'Invalid input');
return data;
}
}Generate Middleware
nextrush g middleware request-loggerCreates src/middleware/request-logger.ts:
import type { Middleware } from 'nextrush';
export const requestLogger: Middleware = async (ctx) => {
const start = Date.now();
await ctx.next();
const duration = Date.now() - start;
console.log(`${ctx.method} ${ctx.path} ${ctx.status} ${duration}ms`);
};Generate a Guard
nextrush g guard authCreates src/guards/auth.guard.ts:
import type { GuardFn } from 'nextrush/class';
export const authGuard: GuardFn = async (ctx) => {
const token = ctx.get('authorization');
if (!token) return false;
// TODO: Validate token
return true;
};Generate a Route
nextrush g route productCreates src/routes/product.ts — a named-export router, matching the functional
template's mounting idiom (import { productRouter } from './routes/product.js' +
app.route('/product', productRouter)):
import { createRouter } from 'nextrush';
export const productRouter = createRouter();
productRouter.get('/', (ctx) => {
ctx.json([]);
});
productRouter.get('/:id', (ctx) => {
ctx.json({ id: ctx.params.id });
});
productRouter.post('/', (ctx) => {
ctx.status = 201;
ctx.json(ctx.body);
});Output Directories
| Type | Default Directory | Module project (src/modules/ exists) | File Suffix |
|---|---|---|---|
| module | src/modules/<name>/ | src/modules/<name>/ | .module.ts |
| controller | src/controllers/ | src/modules/<name>/ | .controller.ts |
| service | src/services/ | src/modules/<name>/ | .service.ts |
| middleware | src/middleware/ | src/middleware/ | .ts |
| guard | src/guards/ | src/guards/ | .guard.ts |
| route | src/routes/ | src/routes/ | .ts |
In a class-based project (one with a src/modules/ directory), controllers and services
co-locate inside their feature module so the module, controller, service, and tests live
together. In module-less (functional/full) projects they use the flat directories above.
Directories are created automatically if they don't exist.
Naming Convention
Names must be lowercase with optional hyphens. The generator converts them to PascalCase for class names and camelCase for function names:
| Input | Class Name | Function Name |
|---|---|---|
user | UserController | user |
user-profile | UserProfileController | userProfile |
auth | AuthController | authGuard |
Wiring generated files
Generators create files; they do not edit existing source. Add generated modules to
your root module's imports, mount generated routes with app.route(...), and register
guards/middleware where they apply.
Existing Files
The generator will not overwrite existing files. If the target file already exists, the command exits with an error.