nest-scramble
v3.0.6
Published
A next-generation, decorator-free API documentation engine with Postman generation, live mocking, and typed client SDK generation for NestJS 10 and 11, engineered by Mohamed Mustafa
Maintainers
Readme
Nest-Scramble
Zero-config API Documentation, Postman Generator & Typed Client SDK for NestJS — powered by static TypeScript analysis
What's New in v3.0.6
Typed HTTP Client SDK Generation ✨
The biggest quality-of-life addition yet. Nest-Scramble can now generate a fully-typed TypeScript API client directly from your NestJS controllers — no OpenAPI tooling required, no extra decorators, zero dependencies in the output.
npx nest-scramble generate src --format client --output ./api-client.tsGenerated output (api-client.ts):
// Auto-generated by nest-scramble v3.0.6 — do not edit manually
// Re-generate: npx nest-scramble generate src --format client
export class UsersApiClient {
constructor(private readonly baseUrl: string) {}
async getUsers(page?: number, limit?: number): Promise<UserListDto[]> {
const url = new URL(`${this.baseUrl}/users`);
if (page !== undefined) url.searchParams.set('page', String(page));
if (limit !== undefined) url.searchParams.set('limit', String(limit));
const res = await fetch(url.toString());
return res.json();
}
async createUser(body: CreateUserDto): Promise<UserDto> {
const res = await fetch(`${this.baseUrl}/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
return res.json();
}
async deleteUser(id: string): Promise<void> {
await fetch(`${this.baseUrl}/users/${id}`, { method: 'DELETE' });
}
}Use it anywhere — frontend, E2E tests, microservices:
import { UsersApiClient } from './api-client';
const client = new UsersApiClient('http://localhost:3000');
const users = await client.getUsers(1, 10); // fully typed ✅No extra runtime packages. Uses native fetch. Stays in sync with your controllers by re-running the command.
Other v3.0.6 changes
- Controller-based sidebar grouping is now the default (no config needed)
- Route param normalisation
:id→{id}for full OpenAPI compliance - Scalar standalone HTML integration for more reliable docs rendering
baseUrlis now respected exactly as configured in the dashboard
Why Nest-Scramble
No @ApiProperty decorators. No runtime overhead. Nest-Scramble reads your TypeScript source using AST analysis and automatically produces:
| | Nest-Scramble | @nestjs/swagger |
|---|---|---|
| Analysis | Static AST (compile-time) | Runtime reflection |
| Decorators required | None | @ApiProperty everywhere |
| Circular references | Auto-detected | Manual workarounds |
| Performance overhead | Zero | Decorator cost on every request |
| Postman collection | Built-in | Third-party export |
| Typed client SDK | ✅ v3.0.6 | ✗ |
Quick Start
Option A — Auto-inject (30 seconds)
npm install nest-scramble
npx nest-scramble init
npm run start:dev
# Visit http://localhost:3000/docsThe init command patches your app.module.ts automatically.
Option B — Manual
1. Install
npm install nest-scramble
# yarn add nest-scramble
# pnpm add nest-scramble2. Register the module
import { Module } from '@nestjs/common';
import { NestScrambleModule } from 'nest-scramble';
@Module({
imports: [NestScrambleModule.forRoot()], // zero-config
})
export class AppModule {}3. Start your app
npm run start:devTerminal output:
╔═══════════════════════════════════════════════════════╗
║ ✨ NEST-SCRAMBLE by Mohamed Mustafa ║
║ ║
║ ● Docs → http://localhost:3000/docs ║
║ ● OpenAPI → http://localhost:3000/docs-json ║
║ ● Mock → http://localhost:3000/scramble-mock ║
║ ║
║ 📦 Source: src 🎯 Controllers: 5 ║
╚═══════════════════════════════════════════════════════╝Configuration
NestScrambleModule.forRoot({
sourcePath: 'src', // default: 'src'
baseUrl: 'http://localhost:3000', // default: auto-detected from PORT/HOST
path: '/docs', // default: '/docs'
enableMock: true, // default: true
autoExportPostman: false, // default: false
postmanOutputPath: 'collection.json', // default: 'collection.json'
theme: 'futuristic', // 'classic' | 'futuristic'
primaryColor: '#00f2ff', // any hex colour
customDomainIcon: '', // favicon URL
apiTitle: 'My API', // default: from package.json
apiVersion: '1.0.0', // default: from package.json
useIncrementalScanning: false, // faster startup via caching
enableWatchMode: false, // auto-regenerate on file changes
cacheTtl: 86400000, // cache TTL in ms (default: 24h)
})| Option | Type | Default | Description |
|--------|------|---------|-------------|
| sourcePath | string | 'src' | Directory containing your controllers |
| baseUrl | string | auto | Base URL shown in docs and mock server |
| path | string | '/docs' | Documentation UI endpoint |
| enableMock | boolean | true | Enable /scramble-mock/* proxy endpoints |
| autoExportPostman | boolean | false | Write Postman collection on startup |
| theme | 'classic' \| 'futuristic' | 'futuristic' | UI theme |
| primaryColor | string | '#00f2ff' | Accent colour (hex) |
| useIncrementalScanning | boolean | false | Cache AST results between restarts |
| enableWatchMode | boolean | false | Re-scan on file save |
| cacheTtl | number | 86400000 | Cache lifetime in milliseconds |
CLI Reference
# Generate OpenAPI JSON
npx nest-scramble generate src -o openapi.json
# Generate Postman collection
npx nest-scramble generate src --format postman -o collection.json
# Generate typed TypeScript client (NEW in v3.0.4, updated in v3.0.6)
npx nest-scramble generate src --format client -o api-client.ts
# Custom options
npx nest-scramble generate src \
-o my-api.json \
-t "My API" \
-v "2.0.0" \
-b "https://api.example.com"
# Check version
npx nest-scramble --versionAll generate options:
| Flag | Description | Default |
|------|-------------|---------|
| -o, --output <file> | Output file path | openapi.json |
| -f, --format <type> | openapi | postman | client | openapi |
| -b, --baseUrl <url> | API base URL | http://localhost:3000 |
| -t, --title <title> | API title | NestJS API |
| -v, --apiVersion <ver> | API version | 1.0.0 |
Programmatic API
import { ScannerService, OpenApiTransformer, PostmanCollectionGenerator } from 'nest-scramble';
import * as fs from 'fs';
const scanner = new ScannerService();
const controllers = scanner.scanControllers('src');
// OpenAPI spec
const transformer = new OpenApiTransformer('http://localhost:3000');
const spec = transformer.transform(controllers, 'My API', '1.0.0', 'http://localhost:3000');
fs.writeFileSync('openapi.json', JSON.stringify(spec, null, 2));
// Postman collection
const postman = new PostmanCollectionGenerator('http://localhost:3000');
const collection = postman.generateCollection(controllers);
fs.writeFileSync('collection.json', JSON.stringify(collection, null, 2));Advanced: Incremental Scanning & Watch Mode
Enable for 10–100× faster restarts on large projects.
NestScrambleModule.forRoot({
useIncrementalScanning: true, // cache AST results to scramble-cache.json
enableWatchMode: true, // recompute only changed files
cacheTtl: 86400000, // invalidate after 24h
})Cache is invalidated automatically when file content, file size, tsconfig.json, or the library version changes.
Add to .gitignore:
scramble-cache.json
.scramble-cache.jsonBenchmark (typical project):
| Scenario | Time | |---|---| | Cold start (no cache) | ~2100 ms | | Warm cache (full) | ~50 ms | | Single file changed | ~20 ms | | DTO changed (5 dependents) | ~100 ms |
Programmatic incremental scanner:
import { IncrementalScannerService } from 'nest-scramble';
const scanner = new IncrementalScannerService({ useCache: true });
scanner.initialize('src');
const controllers = scanner.scanControllers('src');
scanner.cleanup();Live Mocking
With enableMock: true (default), all routes are available under /scramble-mock/* with realistic auto-generated data — no database, no environment setup needed.
GET /scramble-mock/users/1
# → { "id": 1, "name": "Jane Smith", "email": "[email protected]", "createdAt": "..." }Mock values are field-name-aware:
email→faker.internet.email()name/fullName→faker.person.fullName()createdAt/updatedAt→faker.date.recent()id→ incremental integer- Arrays → 2–5 auto-generated items
Documentation UI
Visit /docs for the interactive dashboard:
- Sidebar navigation — endpoints grouped by controller, collapsible
- Three-column layout — Info | Request Editor | Test Panel
- Live request sender — test endpoints directly in the browser
- Pre-filled mock data — request bodies auto-populated
- Theme options —
futuristic(dark, cyan accents) orclassic(light) - Search — press
Kto filter endpoints instantly
Custom branding:
NestScrambleModule.forRoot({
theme: 'futuristic',
primaryColor: '#a855f7', // electric purple
customDomainIcon: '/logo.png',
apiTitle: 'My Platform API',
})Available endpoints:
| Endpoint | Description |
|----------|-------------|
| GET /docs | Interactive Scalar UI |
| GET /docs-json | OpenAPI 3.0 JSON spec |
| GET /docs/spec | OpenAPI spec as JSON response |
CI/CD Integration
# .github/workflows/docs.yml
name: Generate API Docs
on:
push:
branches: [main]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with: { node-version: '20' }
- run: npm install
- run: npx nest-scramble generate src -o openapi.json
- uses: actions/upload-artifact@v3
with:
name: openapi-spec
path: openapi.jsonSupported Types & Decorators
TypeScript types:
- Primitives:
string,number,boolean - Arrays, nested objects, union types
- Enums, optional properties
- Circular references (auto-detected and resolved)
NestJS decorators:
- HTTP methods:
@Get,@Post,@Put,@Patch,@Delete - Parameters:
@Param,@Query,@Body - Controllers:
@Controller(path & group name)
Troubleshooting
No controllers found
Verify sourcePath points to the directory containing your @Controller() classes. On startup, Nest-Scramble logs the exact path it is scanning.
NestScrambleModule.forRoot({ sourcePath: 'src' })/docs returns 401 Unauthorized
Your global AuthGuard is blocking the docs route. Add an isPublic bypass:
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) { super(); }
canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
context.getHandler(),
context.getClass(),
]);
return isPublic ? true : super.canActivate(context);
}
}Nest-Scramble marks its own endpoints with @SetMetadata('isPublic', true) automatically.
OpenAPI spec is empty or incomplete
Ensure your controller methods declare an explicit return type:
// ✅ Good
@Get(':id')
getUser(@Param('id') id: string): UserDto { ... }
// ❌ Missing return type — DTO cannot be inferred
@Get(':id')
getUser(@Param('id') id: string) { ... }TypeScript compilation errors after install
rm -rf node_modules package-lock.json
npm install
npm run buildWhen reporting an issue, include: Nest-Scramble version, NestJS version, Node.js version, TypeScript version, startup log output.
Requirements
| Requirement | Minimum Version | |---|---| | Node.js | 18.10.0 | | TypeScript | 5.0.0 | | NestJS | 10.x or 11.x | | reflect-metadata | 0.1.13 (optional) |
Upgrading from v2.x
npm install @nestjs/common@^10 @nestjs/core@^10
npm install nest-scramble@latestRoadmap
- [x] OpenAPI 3.0 generation (static AST)
- [x] Interactive Scalar UI with controller grouping
- [x] Postman collection export
- [x] Live mock server
- [x] Incremental scanning & watch mode
- [x] Transitive dependency tracking
- [x] Typed TypeScript client SDK (v3.0.6)
- [ ] Insomnia / Bruno collection export
- [ ]
@ScrambleDoc()lightweight metadata decorator - [ ] GraphQL schema support
- [ ] Plugin API for custom analyzers
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new behaviour
- Submit a pull request
License
MIT — see LICENSE.
