Introduction to HazelJS

CodecovNPM VersionLicense

An AI-native backend framework built with TypeScript. Production-grade Agent Runtime, Agentic RAG, and persistent memory β€” designed for stateful AI agents and LLM-powered applications. Build with decorators, dependency injection, and a modular architecture.

🎯What is HazelJS?

HazelJS is an AI-native Node.js framework designed for building intelligent, stateful backend applications. It combines production-grade Agent Runtime, Agentic RAG, and built-in AI integration with enterprise features: dependency injection, type safety, and a modular architecture. AI is at the core of every design decisionβ€”not bolted on.

Core Philosophy

  • πŸ€–AI-Native: Agent Runtime, Agentic RAG, and persistent memory built inβ€”not bolted on
  • ✨Developer Experience: Decorator-based API with @Agent, @Tool, @SemanticSearchβ€”easy to learn and use
  • πŸ”’Type Safety: Built with TypeScript from the ground up for compile-time safety
  • 🧩Modularity: Pick and choose only the packages you needβ€”@hazeljs/ai, @hazeljs/agent, @hazeljs/rag, and more
  • πŸ—οΈEnterprise Ready: Dependency injection, advanced routing, testing, and production features

πŸ—οΈ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:#fff

Modules 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:

  1. Routing: Framework matches the request to a controller method
  2. Middleware: Global and route-specific middleware execute
  3. Guards: Authentication and authorization checks
  4. Interceptors: Request transformation before handler
  5. Pipes: Parameter validation and transformation
  6. Handler: Controller method executes business logic
  7. Interceptors: Response transformation after handler
  8. Exception Filters: Error handling if exceptions occur
  9. 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.

vs NestJS

  • βœ“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.

πŸ’»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.