C
CanxJS
v1.6.2
  • Learn
  • Blog
  • Showcase
C
CanxJS

Ultra-fast async MVC backend framework for Bun. Build production-ready APIs with elegance and speed.

Resources

  • Documentation
  • Learn
  • Blog
  • Showcase

Documentation

  • Introduction
  • Installation
  • Core Concepts
  • CLI Commands
  • API Reference

Legal

  • Privacy Policy
  • Terms of Service

© 2026 CanxJS. All rights reserved.

Built with ❤️ for Candra Kirana

  • Routing
  • Controllers
  • API Resources
  • Dependency Injection
  • Service Providers
  • Middleware
  • Request & Response
  • Authentication
  • Validation
  • Session
  • I18n
  • Utilities
Core Concepts

Dependency Injection

Manage your application's dependencies with a powerful IoC Container. Support for Singletons, Transients, and Request-scoped services.

Auto-Wiring

Automatically resolves constructor dependencies.

Scopes

Singleton, Transient, and Request-scoped bindings.

Interface Binding

Bind concrete classes to abstract tokens/symbols.

Basic Usage

Use @Injectable() to mark classes as dependencies. The container automatically resolves constructor parameters.

services.ts
1import { Injectable, Inject, container } from "canxjs";
2
3@Injectable()
4class ConfigService {
5 constructor() {
6 console.log("ConfigService initialized");
7 }
8
9 get(key: string) {
10 return process.env[key];
11 }
12}
13
14@Injectable()
15class UserService {
16 constructor(
17 private config: ConfigService // Auto-wired
18 ) {}
19
20 getUser() {
21 const dbName = this.config.get("DB_NAME");
22 // ...
23 }
24}
25
26// Resolve instance (ConfigService is auto-injected)
27const userService = await container.resolve(UserService);

Interface Binding

Decouple your code by injecting interfaces (via tokens) instead of concrete classes.

mail.ts
1// Define a token for the interface
2const MAIL_PROVIDER = Symbol("MAIL_PROVIDER");
3
4interface MailProvider {
5 send(to: string, body: string): void;
6}
7
8@Injectable()
9class SmtpMailer implements MailProvider {
10 send(to, body) { console.log('Sending via SMTP'); }
11}
12
13@Injectable()
14class MockMailer implements MailProvider {
15 send(to, body) { console.log('Mock email sent'); }
16}
17
18// Bind implementation to token
19container.bind(MAIL_PROVIDER, SmtpMailer);
20
21@Injectable()
22class NotificationService {
23 constructor(
24 @Inject(MAIL_PROVIDER) private mailer: MailProvider
25 ) {}
26
27 notify() {
28 this.mailer.send('user@example.com', 'Hello');
29 }
30}

Scopes

Control the lifecycle of your dependencies.

scopes.ts
1import { Injectable, Scope } from "canxjs";
2
3// Singleton (Default) - One instance per application
4@Injectable({ scope: Scope.DEFAULT })
5class SingletonService {}
6
7// Transient - New instance every time it's resolved
8@Injectable({ scope: Scope.TRANSIENT })
9class TransientService {}
10
11// Request - One instance per HTTP request
12@Injectable({ scope: Scope.REQUEST })
13class RequestContextService {
14 constructor(@Inject("request") private req: any) {}
15}

Next Steps

Learn how modules organize your application.