A high-performance, decorator-driven DI web framework running on Bun Runtime.
- Why Bun Server
- Features
- Architecture
- Getting Started
- Examples & Extensions
- Benchmark Suite
- Docs & Localization
- Roadmap
- AI-Assisted Development
- Engineering Guidelines
- Contributing
- License
- Other Languages
- Native Bun: built on top of
Bun.serve, embracing native TS, fast I/O and the Bun package manager. - Modern DX: decorators, metadata and DI everywhere — controllers, services, middleware, validation.
- Lightweight yet extensible: modular DI + extension layer + logging provider that scales from MVP to enterprise.
- Well-tested: unit, integration, stress and benchmark suites ship with the repo.
- AI-friendly: source code and tests are included in the npm package, enabling AI tools (like Cursor) to provide better code analysis, suggestions, and understanding of the framework internals.
- 🚀 Fast HTTP stack powered by Bun with
Application,Router,ContextandResponseBuilderhelpers. - 🧩 Dependency injection container with
@Injectable,@Inject, module metadata, lifecycle management and cached dependency plans. - 🧵 Middleware pipeline with global/class/method scopes plus built-ins (logging, error, CORS, upload, static, ...).
- ✅ Input validation via decorators and
ValidationErrorintegration. - 📡 WebSocket gateways with
@WebSocketGateway,@OnMessage, etc. - 📚 Docs & samples including multi-language docs, benchmark scripts and best practices.
Application (Controllers / Modules / DI)
↓
Middleware Pipeline
↓
Router + Context + Response
↓
Bun Runtime
- Bun ≥
1.3.3
Critical: Ensure your tsconfig.json includes these decorator settings:
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}Without these, dependency injection will fail (injected services will be undefined). See Troubleshooting Guide for details.
bun installimport { Application, Controller, GET, Injectable } from "@dangao/bun-server";
@Injectable()
class HealthService {
public ping() {
return { status: "ok" };
}
}
@Controller("/api")
class HealthController {
public constructor(private readonly service: HealthService) {}
@GET("/health")
public check() {
return this.service.ping();
}
}
const app = new Application({ port: 3100 });
app.getContainer().register(HealthService);
app.registerController(HealthController);
app.listen();bun --cwd=packages/@dangao/bun-server test
bun --cwd=packages/@dangao/bun-server run bench
bun --cwd=packages/@dangao/bun-server run bench:router
bun --cwd=packages/@dangao/bun-server run bench:diRunning
bun testfrom the repo root fails because Bun only scans the current workspace. Use the commands above orcd packages/@dangao/bun-serverfirst.
This example demonstrates using interfaces with Symbol tokens and module-based dependency injection:
import {
Application,
Body,
CONFIG_SERVICE_TOKEN,
ConfigModule,
ConfigService,
Controller,
GET,
Inject,
Injectable,
Module,
Param,
POST,
} from "@dangao/bun-server";
// Define service interface
interface UserService {
find(id: string): Promise<{ id: string; name: string } | undefined>;
create(name: string): { id: string; name: string };
}
// Create Symbol token for DI
const UserService = Symbol("UserService");
// Implement the interface
@Injectable()
class UserServiceImpl implements UserService {
private readonly users = new Map<string, { id: string; name: string }>([
["1", { id: "1", name: "Alice" }],
]);
public async find(id: string) {
return this.users.get(id);
}
public create(name: string) {
const id = String(this.users.size + 1);
const user = { id, name };
this.users.set(id, user);
return user;
}
}
@Controller("/api/users")
class UserController {
public constructor(
private readonly service: UserService,
@Inject(CONFIG_SERVICE_TOKEN) private readonly config: ConfigService,
) {}
@GET("/:id")
public async getUser(@Param("id") id: string) {
const user = await this.service.find(id);
if (!user) {
return { error: "Not Found" };
}
return user;
}
@POST("/")
public createUser(@Body("name") name: string) {
return this.service.create(name);
}
}
// Define module with Symbol-based provider
@Module({
controllers: [UserController],
providers: [
{
provide: UserService,
useClass: UserServiceImpl,
},
],
exports: [UserService],
})
class UserModule {}
// Configure modules
ConfigModule.forRoot({
defaultConfig: {
app: {
name: "Advanced App",
port: 3100,
},
},
});
// Register module and start application
@Module({
imports: [ConfigModule],
controllers: [UserController],
providers: [
{
provide: UserService,
useClass: UserServiceImpl,
},
],
})
class AppModule {}
const app = new Application({ port: 3100 });
app.registerModule(AppModule);
app.listen();Key points:
- Interface-based design: Define contracts with TypeScript interfaces
- Symbol tokens: Use
Symbol()for type-safe dependency injection tokens - Module providers: Register providers using
provide: Symbol, useClass: Implementation - Type-safe injection: Inject services using
@Inject(Symbol)with interface types
examples/basic-app.ts: minimal DI + Logger + Middleware showcase.examples/full-app.ts: advanced controllers, validation, uploads, WebSocket.packages/@dangao/bun-server/src/extensions/: official extensions (e.g.LoggerExtension) for plugging in external capabilities.
Benchmarks live in benchmark/ and rely on PerformanceHarness &
StressTester.
| Script | Description |
|---|---|
router.bench.ts |
static/dynamic route hits, router.handle and stress runs |
di.bench.ts |
singleton vs factory resolves, nested dependencies, concurrent stress |
Run directly:
bun benchmark/router.bench.ts
bun benchmark/di.bench.tsOr use bun run bench* scripts for convenience.
- English (default):
docs/api.md,docs/guide.md,docs/best-practices.md,docs/migration.md,docs/extensions.md,docs/deployment.md,docs/performance.md,docs/troubleshooting.md,docs/error-handling.md. - Chinese: mirrored under
docs/zh/. If something is missing, please fall back to the English source.
Detailed milestones and history are tracked in
.roadmap/v0.3.0.md.
Bun Server is designed to work seamlessly with AI coding assistants like Cursor, GitHub Copilot, and others. The framework includes source code and tests in the npm package distribution, enabling AI tools to:
- Understand framework internals: AI can analyze the actual implementation code, not just type definitions, providing more accurate suggestions.
- Provide context-aware help: When you ask about framework features, AI can reference the actual source code to give precise answers.
- Suggest best practices: AI can learn from the framework's patterns and suggest similar approaches in your code.
- Debug more effectively: AI can trace through the framework code to help diagnose issues.
-
Reference framework source: When working with Bun Server, AI tools can access the source code at
node_modules/@dangao/bun-server/src/to understand implementation details. -
Use type hints: The framework provides comprehensive TypeScript types. Leverage these in your code to help AI understand your intent better.
-
Follow framework patterns: The included source code serves as a reference for framework patterns. Ask AI to suggest code that follows similar patterns.
-
Leverage test examples: The included test files demonstrate usage patterns and edge cases. Reference these when asking AI for implementation help.
-
Ask specific questions: Since AI can access the framework source, you can ask specific questions like "How does the DI container resolve dependencies?" and get accurate answers based on the actual code.
- Comments & log messages must be in English to keep the codebase international-friendly.
- Documentation defaults to English; Chinese copies live in
docs/zh/. - Benchmarks belong to
benchmark/and should run inside Bun environments.
- Fork & create a feature branch.
- Run
bun test(and relevant benchmarks if the change affects performance). - Submit a PR with a clear description and test evidence.
Issues and discussions are welcome for new ideas or perf bottlenecks.
Released under the MIT License.
Enjoy building on Bun Server!