embrix
v1.0.1
Published
Production-ready local text embeddings using @xenova/transformers. Supports MiniLM and BGE models with zero external dependencies.
Downloads
217
Maintainers
Readme
embrix
Production-ready local text embeddings using @xenova/transformers. Zero external API calls, runs entirely in Node.js.
Features
- Local Execution - No API calls, runs entirely on your machine
- Two Optimized Models - MiniLM and BGE for different use cases
- Zero Dependencies - Only
@xenova/transformersas dependency - Type-Safe - Full TypeScript support with strict typing
- Efficient - Lazy loading, singleton pattern, batch processing
- Benchmark Tools - Built-in performance measurement utilities
Installation
npm install embrixQuick Start
import { Embedder, EmbeddingModel, cosineSimilarity } from 'embrix';
// Create an embedder
const embedder = new Embedder(EmbeddingModel.MiniLM);
// Generate a single embedding
const embedding = await embedder.embed("Hello, world!");
console.log(embedding.length); // 384
// Generate batch embeddings
const embeddings = await embedder.embedBatch([
"Hello, world!",
"Goodbye, world!"
]);
// Compare similarity
const hello = await embedder.embed("Hello!");
const goodbye = await embedder.embed("Goodbye!");
const similarity = cosineSimilarity(hello, goodbye);
console.log(`Similarity: ${similarity}`);Supported Models
| Model | Enum | Dimensions | Description |
|-------|------|------------|-------------|
| all-MiniLM-L6-v2 | EmbeddingModel.MiniLM | 384 | Fast and efficient, great for most use cases |
| bge-small-en-v1.5 | EmbeddingModel.BGE | 384 | High quality English embeddings from BAAI |
API Reference
Embedder Class
import { Embedder, EmbeddingModel } from 'embrix';
const embedder = new Embedder(EmbeddingModel.MiniLM);Properties
dimension: number- Embedding dimension (384 for both models)modelName: string- Human-readable model namemodelType: EmbeddingModel- The model enum value
Methods
embed(text: string, options?): Promise<Float32Array>
Generate an embedding for a single text.
const vector = await embedder.embed("Your text here");embedBatch(texts: string[], options?): Promise<Float32Array[]>
Generate embeddings for multiple texts efficiently.
const vectors = await embedder.embedBatch(["Text 1", "Text 2", "Text 3"]);embedWithMetadata(text: string, options?): Promise<EmbeddingResult>
Generate embedding with full metadata.
const result = await embedder.embedWithMetadata("Your text");
console.log(result.model); // EmbeddingModel.MiniLM
console.log(result.dimension); // 384
console.log(result.embedding); // Float32ArraySimilarity Functions
import {
cosineSimilarity,
dotProduct,
euclideanDistance,
manhattanDistance,
findMostSimilar,
findKMostSimilar
} from 'embrix';cosineSimilarity(a: Float32Array, b: Float32Array): number
Calculate cosine similarity between two vectors. Range: [-1, 1].
const similarity = cosineSimilarity(vector1, vector2);dotProduct(a: Float32Array, b: Float32Array): number
Calculate dot product of two vectors.
const product = dotProduct(vector1, vector2);euclideanDistance(a: Float32Array, b: Float32Array): number
Calculate Euclidean (L2) distance between two vectors.
const distance = euclideanDistance(vector1, vector2);findMostSimilar(query: Float32Array, candidates: Float32Array[])
Find the most similar vector to a query.
const query = await embedder.embed("search query");
const docs = await embedder.embedBatch(["doc 1", "doc 2", "doc 3"]);
const best = findMostSimilar(query, docs);
console.log(`Best match: index ${best.index}, similarity ${best.similarity}`);findKMostSimilar(query: Float32Array, candidates: Float32Array[], k: number)
Find the k most similar vectors.
const top5 = findKMostSimilar(query, docs, 5);Model Loading
import { preloadModel, preloadAllModels, isModelLoaded, clearModelCache } from 'embrix';
// Preload a specific model
await preloadModel(EmbeddingModel.MiniLM);
// Preload all models
await preloadAllModels();
// Check if model is loaded
if (isModelLoaded(EmbeddingModel.MiniLM)) {
// Model is ready
}
// Clear cache to free memory
clearModelCache();Benchmark Utilities
import { runBenchmark, runAllBenchmarks, formatBenchmarkResult } from 'embrix';
// Benchmark a single model
const results = await runBenchmark(EmbeddingModel.MiniLM);
console.log(formatBenchmarkResult(results));
// Benchmark all models
const allResults = await runAllBenchmarks();CLI Benchmark
Run benchmarks from the command line:
npm run benchmark
# Options
npm run benchmark -- --model minilm
npm run benchmark -- --batch-size 50
npm run benchmark -- --helpExperimental Benchmark Results
For comprehensive experimental benchmark results, including performance comparisons across different models and configurations, see the test-embrix-experimental repository.
Example Output
============================================================
Benchmark: all-MiniLM-L6-v2
Model: minilm
Dimension: 384
============================================================
Running cold start benchmark...
Duration: 2345.67ms
Running warm start benchmark...
Duration: 12.34ms
Speedup: 190.15x faster than cold start
Running batch benchmark (100 texts)...
Total duration: 567.89ms
Avg per embedding: 5.68ms
Throughput: 176.09 embeddings/secArchitecture
embrix/
├── src/
│ ├── models.ts # Model definitions and metadata
│ ├── loader.ts # Lazy singleton model loader
│ ├── embedder.ts # Core embedding class
│ ├── similarity.ts # Vector similarity functions
│ ├── benchmark.ts # Performance measurement utilities
│ └── index.ts # Barrel export
├── scripts/
│ └── benchmark.ts # CLI benchmark script
├── examples/
│ └── usage.ts # Usage examples
├── package.json
├── tsconfig.json
└── README.mdDesign Decisions
Lazy Singleton Loading
Models are loaded on-demand and cached in memory. This ensures:
- Fast subsequent calls (warm start)
- No duplicate model loads
- Memory efficiency
Float32Array Throughout
All embeddings are returned as Float32Array for:
- Consistency with the underlying tensor output
- Memory efficiency vs regular arrays
- Compatibility with WebAssembly and GPU operations
No External Dependencies
Only @xenova/transformers is required. This keeps the package:
- Lightweight
- Secure
- Easy to audit
Requirements
- Node.js >= 18.0.0
- ~500MB disk space for model cache (first run)
Citation
If you use embrix in your research, please cite:
@software{embrix2026,
title = {embrix: Production-Ready Local Text Embeddings for Node.js},
author = {Tahsin Özgür Koç},
year = {2026},
url = {https://github.com/tahsinkoc/embrix}
}License
MIT
