Introduction to HazelJS
Agent OS for TypeScript backends — durable AI agents inside the same DI/HTTP app as your APIs. DNA packages, crash-safe HITL, Skillgate, and local apply. Framework packages (HCEL, RAG, workflows) when you need them — they are not the wedge.
Start here: Clone Meridian (store:sync → platform:sync → npm run dev), then read the Agent OS guide.
What is HazelJS?
HazelJS is a TypeScript Node framework whose primary product is Agent OS: durable agent runs, DNA packaging, Skillgate-governed REST skills, and local apply/reconcile — not a Nest clone and not “47 packages” as the story. Decorators and DI stay familiar; agents are backend jobs, not a chat widget bolted onto Express.
Agent OS wedge
- DNA + Store — version prompt/policies like libraries; tools stay in
@Toolcode - Crash-safe HITL — durable suspend/resume on AgentRun across restarts
- Skillgate + local apply — curated REST skills; declare Definitions without Kubernetes as the product
- Also available — HCEL chains, RAG, workflows when you need them (not the first story)
🏗️Architecture
HazelJS follows a modular, decorator-based architecture that promotes separation of concerns and code reusability. The framework is built on top of a powerful dependency injection system and uses metadata reflection for configuration.
Application Architecture
graph TD
A["HTTP Request"] --> B["Routing Layer<br/>(@Controller, @Get, @Post)"]
B --> C["Middleware Pipeline<br/>(Global & Route-specific)"]
C --> D["Guards<br/>(Authentication & Authorization)"]
D --> E["Interceptors<br/>(Request/Response Transformation)"]
E --> F["Pipes<br/>(Validation & Transformation)"]
F --> G["Controller Handler<br/>(Business Logic)"]
G --> H["Services<br/>(Dependency Injection)"]
H --> I["Data Layer<br/>(Prisma, Cache, External APIs)"]
I --> J["Response"]
style A fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff
style B fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff
style C fill:#10b981,stroke:#34d399,stroke-width:2px,color:#fff
style D fill:#f59e0b,stroke:#fbbf24,stroke-width:2px,color:#fff
style E fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
style F fill:#ec4899,stroke:#f472b6,stroke-width:2px,color:#fff
style G fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff
style H fill:#06b6d4,stroke:#22d3ee,stroke-width:2px,color:#fff
style I fill:#14b8a6,stroke:#2dd4bf,stroke-width:2px,color:#fff
style J fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff📦Modular Design
HazelJS is organized as a monorepo with independent packages. Each package can be installed separately, allowing you to use only what you need.
- •
@hazeljs/core- Core framework - •
@hazeljs/agent- Agent Runtime (stateful AI agents) - •
@hazeljs/ai- AI integration (OpenAI, Anthropic, Ollama) - •
@hazeljs/rag- Agentic RAG and vector search - •
@hazeljs/auth,@hazeljs/cache,@hazeljs/prisma, and more
💉Dependency Injection
Built-in DI container with support for multiple scopes and automatic dependency resolution. No manual wiring required.
- • Singleton scope (default)
- • Transient scope (new instance per injection)
- • Request scope (per HTTP request)
- • Circular dependency detection
- • Property-based injection
Module System
graph LR
A["AppModule<br/>(Root Module)"] --> B["Feature Modules"]
B --> C["UsersModule"]
B --> D["ProductsModule"]
B --> E["AuthModule"]
C --> F["Controllers<br/>Services<br/>Providers"]
D --> F
E --> F
F --> G["DI Container<br/>(Automatic Resolution)"]
style A fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff
style B fill:#10b981,stroke:#34d399,stroke-width:2px,color:#fff
style C fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
style D fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
style E fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
style F fill:#f59e0b,stroke:#fbbf24,stroke-width:2px,color:#fff
style G fill:#06b6d4,stroke:#22d3ee,stroke-width:2px,color:#fffModules encapsulate related functionality. They can import other modules, export providers, and declare controllers. The DI container automatically resolves dependencies across modules.
⚙️Technical Details
Decorator-Based Configuration
HazelJS uses TypeScript decorators and metadata reflection to configure your application. This approach provides a clean, declarative API that's both type-safe and easy to understand.
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get()
findAll() {
return this.usersService.findAll();
}
}Decorators store metadata that the framework uses to set up routing, dependency injection, and middleware automatically.
Request Lifecycle
Every HTTP request goes through a well-defined pipeline:
- Routing: Framework matches the request to a controller method
- Middleware: Global and route-specific middleware execute
- Guards: Authentication and authorization checks
- Interceptors: Request transformation before handler
- Pipes: Parameter validation and transformation
- Handler: Controller method executes business logic
- Interceptors: Response transformation after handler
- Exception Filters: Error handling if exceptions occur
- Response: Final response sent to client
Dependency Injection Container
The DI container is the heart of HazelJS. It manages the lifecycle of all providers and automatically resolves dependencies using reflection metadata.
@Injectable()
export class UsersService {
constructor(
private prisma: PrismaService,
private cache: CacheService
) {}
// Dependencies automatically injected
}The container uses TypeScript's reflection metadata to determine parameter types and automatically provides the correct instances.
💡Why HazelJS?
HazelJS combines the best features of modern Node.js frameworks with a focus on simplicity, performance, and developer experience.
⚡️Enterprise Performance
- ✓Lighter weight with smaller bundle size
- ✓Built-in AI service integration
- ✓Simpler learning curve
- ✓Native Prisma integration
- ✓No Express/Fastify dependency
vs Express
- ✓Decorator-based API
- ✓Built-in dependency injection
- ✓Automatic request validation
- ✓Full TypeScript type safety
- ✓Modular architecture
- ✓Built-in testing utilities
✨Key Features
🎯Decorator-Based API
Clean, intuitive programming model with @Controller,@Injectable,@Get,@Post decorators. Declarative configuration that's easy to read and maintain.
💉Advanced Dependency Injection
Singleton, Transient, and Request-scoped providers with circular dependency detection. Automatic dependency resolution using TypeScript reflection metadata.
🤖Agent Runtime & AI Integration
Production Agent Runtime for stateful AI agents with tools, memory, and human-in-the-loop. Native integration with OpenAI, Anthropic, Gemini, Cohere, and Ollama. Use @Agent, @Tool, @AITask decorators.
🗄️Prisma Integration
First-class ORM support with repository pattern and automatic migrations. Type-safe database access with full TypeScript support.
🛡️Exception Filters & Testing
Centralized error handling with exception filters. Full test module builder with mocking support for easy unit and integration testing.
🛣️Advanced Routing
Wildcards, optional params, API versioning with multiple strategies (URI, Header, Media Type). Flexible routing that adapts to your needs.
🚀Getting Started
Ready to start building with HazelJS? Follow these steps to get up and running in minutes.
💻Quick Example
Here's a simple example to show how easy it is to build with HazelJS:
import { HazelApp, HazelModule, Controller, Get, Injectable } from '@hazeljs/core';
@Injectable()
export class AppService {
getHello() {
return 'Hello from HazelJS!';
}
}
@Controller('hello')
export class HelloController {
constructor(private appService: AppService) {}
@Get()
hello() {
return { message: this.appService.getHello() };
}
}
@HazelModule({
controllers: [HelloController],
providers: [AppService],
})
export class AppModule {}
async function bootstrap() {
const app = new HazelApp(AppModule);
await app.listen(3000);
console.log('🚀 Application running on http://localhost:3000');
}
bootstrap();This example demonstrates dependency injection, routing, and module organization. Visit http://localhost:3000/hello to see it in action.
🤝Community
Join our growing community of developers building with HazelJS. We welcome contributions of all kinds, from bug reports to feature requests and pull requests.