npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hazeljs/ml

v1.0.5

Published

Machine Learning & Model Management for HazelJS framework

Downloads

1,790

Readme

@hazeljs/ml

Machine Learning & Model Management for HazelJS - training, prediction, model registry, and metrics.

npm version npm downloads License: Apache-2.0

Features

  • Model registry – Register and discover models by name and version
  • Decorators@Model, @Train, @Predict for declarative ML APIs
  • Training pipeline – PipelineService for data preprocessing (normalize, filter)
  • Inference – PredictorService for single and batch predictions
  • Metrics – MetricsService for evaluation, A/B testing, and monitoring
  • Framework-agnostic – Works with TensorFlow.js, ONNX, Transformers.js, or custom backends

Installation

npm install @hazeljs/ml @hazeljs/core

Peer dependencies (optional, per use case)

# TensorFlow.js
npm install @tensorflow/tfjs-node

# ONNX Runtime
npm install onnxruntime-node

# Hugging Face Transformers (embeddings, sentiment)
npm install @huggingface/transformers

Quick Start

1. Import MLModule

import { HazelApp } from '@hazeljs/core';
import { MLModule } from '@hazeljs/ml';

const app = new HazelApp({
  imports: [
    MLModule.forRoot({
      models: [SentimentClassifier, SpamClassifier],
    }),
  ],
});

app.listen(3000);

2. Define a model with decorators

import { Injectable } from '@hazeljs/core';
import { Model, Train, Predict, ModelRegistry } from '@hazeljs/ml';

@Model({ name: 'sentiment-classifier', version: '1.0.0', framework: 'custom' })
@Injectable()
export class SentimentClassifier {
  private labels = ['positive', 'negative', 'neutral'];
  private weights: Record<string, number[]> = {};

  constructor(private registry: ModelRegistry) {}

  @Train()
  async train(data: { text: string; label: string }[]): Promise<void> {
    // Your training logic – e.g. bag-of-words, embeddings, etc.
    const vocab = this.buildVocabulary(data);
    this.weights = this.computeWeights(data, vocab);
  }

  @Predict()
  async predict(input: { text: string }): Promise<{ sentiment: string; confidence: number }> {
    const scores = this.score(input.text);
    const idx = scores.indexOf(Math.max(...scores));
    return {
      sentiment: this.labels[idx],
      confidence: scores[idx],
    };
  }
}

3. Predict from a controller or service

import { Controller, Post, Body, Inject } from '@hazeljs/core';
import { PredictorService } from '@hazeljs/ml';

@Controller('ml')
export class MLController {
  constructor(private predictor: PredictorService) {}

  @Post('predict')
  async predict(@Body() body: { text: string; model?: string }) {
    const result = await this.predictor.predict(body.model ?? 'sentiment-classifier', body);
    return { result };
  }
}

ML Decorators

The package uses three decorators to declare ML models and their behaviour. The registry and services discover them via reflection—no manual wiring needed.

@Model (class)

Marks a class as an ML model and attaches registry metadata. Required so the model can be registered and looked up by name/version.

| Property | Type | Required | Description | | ------------- | -------- | -------- | ------------------------------------------------ | | name | string | Yes | Unique model id (e.g. 'sentiment-classifier'). | | version | string | Yes | Semver (e.g. '1.0.0'). | | framework | string | Yes | 'tensorflow' | 'onnx' | 'custom'. | | description | string | No | Human-readable description. | | tags | string[] | No | Tags for filtering (default: []). |

Example: One model per class; use @Injectable() so the app can construct it.

@Model({
  name: 'spam-classifier',
  version: '1.0.0',
  framework: 'custom',
  description: 'Binary spam/ham classifier',
  tags: ['nlp', 'moderation'],
})
@Injectable()
export class SpamClassifier {
  // ...
}

@Train (method)

Marks the single method that trains this model. TrainerService.train(modelName, data) will call it. Optional config is for documentation or pipeline wiring.

| Option | Type | Default | Description | | ----------- | ------ | ----------- | ----------------------------------------------------------------------- | | pipeline | string | 'default' | Name of a registered PipelineService pipeline to run before training. | | batchSize | number | 32 | Hint for batching (your logic can ignore it). | | epochs | number | 10 | Hint for epochs (your logic can ignore it). |

Example: Exactly one @Train() method per model; it receives training data and can return metrics.

@Train({ pipeline: 'sentiment-preprocessing', epochs: 5 })
async train(data: { samples: Array<{ text: string; label: string }> }): Promise<TrainingResult> {
  // Your training logic
  return { accuracy: 0.95, loss: 0.05 };
}

@Predict (method)

Marks the single method that runs inference. PredictorService.predict(modelName, input) will call it.

| Option | Type | Default | Description | | ---------- | ------- | ------------ | ---------------------------------------------------------- | | batch | boolean | false | Hint that the method supports batch input (semantic only). | | endpoint | string | '/predict' | Hint for route naming (semantic only). |

Example: Exactly one @Predict() method per model; it receives one input and returns a prediction object.

@Predict({ batch: true, endpoint: '/predict' })
async predict(input: { text: string }): Promise<{ label: string; confidence: number }> {
  // Your inference logic
  return { label: 'ham', confidence: 0.92 };
}

Rules

  • One model class = one @Model, one @Train method, one @Predict method.
  • Order: Put @Model on the class, then @Train and @Predict on the methods. Use @Injectable() from @hazeljs/core so the app can instantiate the model.
  • Discovery: When you pass model classes to MLModule.forRoot({ models: [...] }), the bootstrap finds the @Train and @Predict methods and registers them with the registry.

Model registration

Models are registered when passed to MLModule.forRoot({ models: [...] }). The bootstrap discovers @Train and @Predict methods via reflection.

Manual registration

import { registerMLModel, ModelRegistry, TrainerService, PredictorService } from '@hazeljs/ml';

// When injecting ModelRegistry in a custom service:
registerMLModel(sentimentInstance, modelRegistry, trainerService, predictorService);

Training pipeline

Preprocess data before training with PipelineService:

import { PipelineService } from '@hazeljs/ml';

const pipeline = new PipelineService();
const steps = [
  {
    name: 'normalize',
    transform: (d: unknown) => ({
      ...(d as object),
      text: (d as { text: string }).text?.toLowerCase(),
    }),
  },
  {
    name: 'filter',
    transform: (d: unknown) => ((d as { text: string }).text?.length > 0 ? d : null),
  },
];
// Inline steps (no registration required)
const processed = await pipeline.run(data, steps);
await model.train(processed);

// Or register a named pipeline
pipeline.registerPipeline('default', steps);
const processed2 = await pipeline.run('default', data);

Batch predictions

import { BatchService } from '@hazeljs/ml';

const batchService = new BatchService(predictorService);
const results = await batchService.predictBatch('sentiment-classifier', items, {
  batchSize: 32,
  concurrency: 4,
});
// Results are returned in the same order as inputs

Metrics and evaluation

import { MetricsService } from '@hazeljs/ml';

// Evaluate model on test data (inject MetricsService via MLModule - it receives PredictorService)
@Injectable()
class EvaluationService {
  constructor(private metricsService: MetricsService) {}

  async runEvaluation() {
    const testData = [
      { text: 'great product', label: 'positive' },
      { text: 'terrible', label: 'negative' },
    ];
    const evaluation = await this.metricsService.evaluate('sentiment-classifier', testData, {
      metrics: ['accuracy', 'f1', 'precision', 'recall'],
      labelKey: 'label', // key in test sample for ground truth
      predictionKey: 'sentiment', // key in prediction result (auto-detect: label, sentiment, class)
    });
    // evaluation.metrics: { accuracy, precision, recall, f1Score }
    // Result is automatically recorded via recordEvaluation()
  }
}

// Manual recording
metricsService.recordEvaluation({
  modelName: 'my-model',
  version: '1.0.0',
  metrics: { accuracy: 0.95, loss: 0.05 },
  evaluatedAt: new Date(),
});

API summary

| Service | Purpose | | ------------------ | --------------------------------------------- | | ModelRegistry | Register and lookup models by name/version | | TrainerService | Discover and invoke @Train methods | | PredictorService | Discover and invoke @Predict methods | | PipelineService | Data preprocessing pipeline | | BatchService | Batch prediction with configurable batch size | | MetricsService | Model evaluation and metrics tracking |

Examples

  • hazeljs-ml-starter – Full app: sentiment, spam, intent classifiers, REST API, training pipeline, and metrics.
  • example/src/ml – Minimal runnable example of the three decorators (npm run ml:decorators from the example repo).

Links