Node.js Quick Start
Get started with Bytedocs in Node.js applications
Bytedocs for Node.js supports the most popular frameworks with automatic route detection and TypeScript support.
Supported Frameworks
- Express - Fast, unopinionated web framework
- Fastify - High performance web framework
- NestJS - Progressive Node.js framework
- Hono - Ultrafast web framework
- Koa - Next generation web framework
- AdonisJS - Full-featured MVC framework
Installation
Choose your framework:
# Express
npm install @bytedocs/express
# Fastify
npm install @bytedocs/fastify
# NestJS
npm install @bytedocs/nestjs
# Hono
npm install @bytedocs/hono
# Koa
npm install @bytedocs/koa
# AdonisJS
npm install @bytedocs/adonisjs
Quick Start Examples
Express
import express from 'express';
import { setupByteDocs } from '@bytedocs/express';
const app = express();
app.use(express.json());
// Setup Bytedocs - One line!
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
description: 'My awesome API',
});
// Define your routes as normal
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id, name: 'John Doe' });
});
app.post('/users', (req, res) => {
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('Docs available at http://localhost:3000/docs');
});
Express with TypeScript
import express, { Request, Response } from 'express';
import { setupByteDocs } from '@bytedocs/express';
interface User {
id: number;
name: string;
email: string;
}
interface CreateUserRequest {
name: string;
email: string;
}
const app = express();
app.use(express.json());
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
});
// TypeScript interfaces are automatically detected
app.get('/users/:id', (req: Request, res: Response<User>) => {
res.json({
id: parseInt(req.params.id),
name: 'John Doe',
email: 'john@example.com'
});
});
app.post('/users', (req: Request<{}, {}, CreateUserRequest>, res: Response<User>) => {
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
});
app.listen(3000);
Fastify
import Fastify from 'fastify';
import { setupByteDocs } from '@bytedocs/fastify';
const fastify = Fastify();
// Setup Bytedocs
setupByteDocs(fastify, {
title: 'My Fastify API',
version: '1.0.0',
});
// Define routes with schema validation
fastify.get('/users/:id', {
schema: {
params: {
type: 'object',
properties: {
id: { type: 'number' }
}
},
response: {
200: {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string' },
email: { type: 'string' }
}
}
}
},
handler: async (request, reply) => {
return {
id: request.params.id,
name: 'John Doe',
email: 'john@example.com'
};
}
});
await fastify.listen({ port: 3000 });
NestJS
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { setupByteDocs } from '@bytedocs/nestjs';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Setup Bytedocs
setupByteDocs(app, {
title: 'My NestJS API',
version: '1.0.0',
});
await app.listen(3000);
}
bootstrap();
// users.controller.ts
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
interface User {
id: number;
name: string;
email: string;
}
class CreateUserDto {
name: string;
email: string;
}
@Controller('users')
export class UsersController {
@Get(':id')
findOne(@Param('id') id: string): User {
return {
id: parseInt(id),
name: 'John Doe',
email: 'john@example.com'
};
}
@Post()
create(@Body() createUserDto: CreateUserDto): User {
return {
id: 1,
...createUserDto
};
}
}
Hono
import { Hono } from 'hono';
import { setupByteDocs } from '@bytedocs/hono';
const app = new Hono();
// Setup Bytedocs
setupByteDocs(app, {
title: 'My Hono API',
version: '1.0.0',
});
app.get('/users/:id', (c) => {
const id = c.req.param('id');
return c.json({ id, name: 'John Doe' });
});
app.post('/users', async (c) => {
const body = await c.req.json();
return c.json({ id: 1, ...body }, 201);
});
export default app;
Koa
import Koa from 'koa';
import Router from '@koa/router';
import bodyParser from 'koa-bodyparser';
import { setupByteDocs } from '@bytedocs/koa';
const app = new Koa();
const router = new Router();
app.use(bodyParser());
// Setup Bytedocs
setupByteDocs(app, router, {
title: 'My Koa API',
version: '1.0.0',
});
router.get('/users/:id', (ctx) => {
ctx.body = {
id: ctx.params.id,
name: 'John Doe'
};
});
router.post('/users', (ctx) => {
ctx.status = 201;
ctx.body = {
id: 1,
...ctx.request.body
};
});
app.use(router.routes());
app.listen(3000);
AdonisJS
// start/routes.ts
import Route from '@ioc:Adonis/Core/Route';
import { setupByteDocs } from '@bytedocs/adonisjs';
// Setup Bytedocs
setupByteDocs({
title: 'My AdonisJS API',
version: '1.0.0',
});
Route.get('/users/:id', 'UsersController.show');
Route.post('/users', 'UsersController.store');
// app/Controllers/Http/UsersController.ts
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
export default class UsersController {
public async show({ params, response }: HttpContextContract) {
return response.json({
id: params.id,
name: 'John Doe'
});
}
public async store({ request, response }: HttpContextContract) {
const body = request.only(['name', 'email']);
return response.status(201).json({
id: 1,
...body
});
}
}
Configuration Options
Basic Configuration
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
description: 'API description',
docsPath: '/docs', // Default: '/docs'
autoDetect: true, // Default: true
});
Multiple Environments
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
baseUrls: [
{ name: 'Production', url: 'https://api.example.com' },
{ name: 'Staging', url: 'https://staging.example.com' },
{ name: 'Local', url: 'http://localhost:3000' },
],
});
With Authentication
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
auth: {
enabled: true,
type: 'session',
username: 'admin',
password: process.env.DOCS_PASSWORD,
},
});
With AI Assistant
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
ai: {
enabled: true,
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4o-mini',
},
});
Auto-Detection Features
1. Route Parameters
// Path parameters
app.get('/users/:id', (req, res) => {
const id = req.params.id; // Auto-detected
// ...
});
// Query parameters
app.get('/users', (req, res) => {
const page = req.query.page; // Auto-detected
// ...
});
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (req, res) => {
// Both parameters auto-detected
});
2. Request Body (TypeScript)
interface CreateUserDto {
name: string;
email: string;
age?: number;
}
app.post('/users', (req: Request<{}, {}, CreateUserDto>, res) => {
// CreateUserDto schema automatically documented
const { name, email, age } = req.body;
// ...
});
3. Response Types (TypeScript)
interface User {
id: number;
name: string;
email: string;
createdAt: Date;
}
app.get('/users/:id', (req, res: Response<User>) => {
// User schema automatically documented
res.json({
id: 1,
name: 'John',
email: 'john@example.com',
createdAt: new Date()
});
});
4. Validation with Zod
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().min(0).max(150).optional(),
});
app.post('/users', (req, res) => {
const data = CreateUserSchema.parse(req.body);
// Schema automatically documented with validation rules
// ...
});
5. JSDoc Annotations
/**
* Get user by ID
* @summary Retrieve a specific user
* @tag Users
* @param id path number true "User ID"
* @response 200 {object} User "User object"
* @response 404 {object} Error "User not found"
*/
app.get('/users/:id', (req, res) => {
// ...
});
JSDoc Tags Reference
Basic Tags
/**
* Endpoint title
* @summary Short description
* @description Longer description with details
* @tag TagName
*/
Parameters
/**
* @param name in type required "description"
*
* Examples:
* @param id path number true "User ID"
* @param page query number false "Page number"
* @param Authorization header string true "Bearer token"
*/
Request Body
/**
* @body {object} RequestSchema "Request body description"
*
* Example:
* @body {object} CreateUserRequest "User data"
*/
Responses
/**
* @response status {type} Schema "Description"
*
* Examples:
* @response 200 {object} User "Success"
* @response 201 {object} User "Created"
* @response 400 {object} Error "Bad request"
* @response 404 {object} Error "Not found"
*/
TypeScript Best Practices
1. Define Interfaces
// DTOs (Data Transfer Objects)
interface CreateUserDto {
name: string;
email: string;
password: string;
}
interface UpdateUserDto {
name?: string;
email?: string;
}
// Response types
interface UserResponse {
id: number;
name: string;
email: string;
createdAt: string;
}
// Error types
interface ErrorResponse {
message: string;
errors?: Record<string, string[]>;
}
2. Use Type Assertions
app.post('/users',
(req: Request<{}, {}, CreateUserDto>,
res: Response<UserResponse | ErrorResponse>) => {
// Types are automatically documented
}
);
3. Export Types
// types/user.ts
export interface User {
id: number;
name: string;
email: string;
}
// routes/users.ts
import { User } from '../types/user';
app.get('/users/:id', (req, res: Response<User>) => {
// User type is reused across documentation
});
Middleware Integration
Express Middleware
import { byteDocsAuth } from '@bytedocs/express';
// Protect docs with custom middleware
app.use('/docs', byteDocsAuth({
username: 'admin',
password: process.env.DOCS_PASSWORD,
}));
Custom Authentication
app.use('/docs', (req, res, next) => {
// Custom auth logic
const token = req.headers.authorization;
if (!isValidToken(token)) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
});
Environment Variables
# .env file
BYTEDOCS_TITLE="My API"
BYTEDOCS_VERSION="1.0.0"
BYTEDOCS_DESCRIPTION="My awesome API"
BYTEDOCS_DOCS_PATH=/docs
BYTEDOCS_AUTO_DETECT=true
# Multiple environments
BYTEDOCS_PRODUCTION_URL=https://api.example.com
BYTEDOCS_STAGING_URL=https://staging.example.com
BYTEDOCS_LOCAL_URL=http://localhost:3000
# Authentication
BYTEDOCS_AUTH_ENABLED=true
BYTEDOCS_AUTH_TYPE=session
BYTEDOCS_AUTH_USERNAME=admin
BYTEDOCS_AUTH_PASSWORD=secret
# AI
BYTEDOCS_AI_ENABLED=true
BYTEDOCS_AI_PROVIDER=openai
BYTEDOCS_AI_API_KEY=sk-...
BYTEDOCS_AI_MODEL=gpt-4o-mini
Using in Configuration
import dotenv from 'dotenv';
dotenv.config();
setupByteDocs(app, {
title: process.env.BYTEDOCS_TITLE,
version: process.env.BYTEDOCS_VERSION,
description: process.env.BYTEDOCS_DESCRIPTION,
auth: {
enabled: process.env.BYTEDOCS_AUTH_ENABLED === 'true',
type: process.env.BYTEDOCS_AUTH_TYPE,
username: process.env.BYTEDOCS_AUTH_USERNAME,
password: process.env.BYTEDOCS_AUTH_PASSWORD,
},
ai: {
enabled: process.env.BYTEDOCS_AI_ENABLED === 'true',
provider: process.env.BYTEDOCS_AI_PROVIDER,
apiKey: process.env.BYTEDOCS_AI_API_KEY,
model: process.env.BYTEDOCS_AI_MODEL,
},
});
Production Deployment
Disable in Production
if (process.env.NODE_ENV !== 'production') {
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
});
}
Or Protect with Authentication
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
auth: {
enabled: process.env.NODE_ENV === 'production',
type: 'session',
username: process.env.DOCS_USERNAME,
password: process.env.DOCS_PASSWORD,
},
});
Troubleshooting
Routes Not Appearing
- Ensure routes are registered before Bytedocs:
// ❌ Wrong
setupByteDocs(app, config);
app.get('/users', handler);
// ✅ Correct
app.get('/users', handler);
setupByteDocs(app, config);
- Check route registration:
// For debugging
app._router.stack.forEach(r => {
if (r.route) console.log(r.route.path);
});
TypeScript Types Not Detected
- Enable declaration files:
// tsconfig.json
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": false
}
}
- Use explicit types:
// Instead of implicit any
const handler = (req, res) => { ... }
// Use explicit types
const handler = (req: Request, res: Response) => { ... }
Memory Issues with Large APIs
setupByteDocs(app, {
title: 'My API',
version: '1.0.0',
cache: true, // Enable caching
excludePaths: [ // Exclude unnecessary routes
'/health',
'/metrics',
'/_internal',
],
});
Visit Documentation
Start your server and visit:
http://localhost:3000/docs
What's Next?
- Core Concepts - Understand how Bytedocs works
- Configuration - Advanced configuration
- AI Assistant - Add intelligent chat
- Examples - Complete example projects
On this page