MemberJunction AI provider for local text embeddings using Transformers.js. This package runs embedding models directly on your machine, eliminating the need for external API calls, API keys, or per-token charges.
graph TD
A["LocalEmbedding
(Provider)"] -->|extends| B["BaseEmbeddings
(@memberjunction/ai)"]
A -->|uses| C["Transformers.js
(@huggingface/transformers)"]
C -->|loads from| D["Hugging Face Hub
(or local cache)"]
C -->|runs| E["ONNX model
mean pooling + L2 norm"]
E -->|generates| F["Embedding Vectors"]
B -->|registered via| G["@RegisterClass"]
style A fill:#7c5295,stroke:#563a6b,color:#fff
style B fill:#2d6a9f,stroke:#1a4971,color:#fff
style C fill:#2d8659,stroke:#1a5c3a,color:#fff
style D fill:#b8762f,stroke:#8a5722,color:#fff
style E fill:#2d6a9f,stroke:#1a4971,color:#fff
style F fill:#2d8659,stroke:#1a5c3a,color:#fff
style G fill:#b8762f,stroke:#8a5722,color:#fff
EmbedTexts runs one ONNX call per 32 texts or 8,192 padded tokens, so long documents go one at a timeq8) ONNX weightsos.availableParallelism()), so a container's CPU limit is respecteddimensions keeps the leading values and re-normalizesmaxInputTokens truncates each text in the tokenizer| Model | Dimensions | Description |
|---|---|---|
all-MiniLM-L6-v2 |
384 | Lightweight general-purpose embeddings |
all-MiniLM-L12-v2 |
384 | Higher quality with more layers |
all-mpnet-base-v2 |
768 | Best quality general-purpose embeddings |
paraphrase-multilingual-MiniLM-L12-v2 |
384 | Multilingual support (50+ languages) |
gte-small |
384 | General Text Embeddings (efficient) |
bge-small-en-v1.5 |
384 | BAAI General Embeddings (English) |
Any Hugging Face repo with transformers.js ONNX weights works the same way, for example
onnx-community/embeddinggemma-2-ONNX (768 dimensions, truncatable to 512/256/128, 8,192-token
window). Its catalog row is EmbeddingGemma 2 (Local), which caps inputs at 2,048 tokens to bound memory; it is opt-in through
MJ_DEFAULT_LOCAL_EMBEDDING_MODEL (see plans/embeddinggemma-2-local-embeddings.md).
npm install @memberjunction/ai-local-embeddings
import { LocalEmbedding } from '@memberjunction/ai-local-embeddings';
const embedder = new LocalEmbedding();
const result = await embedder.EmbedText({
text: 'Your text to embed',
model: 'Xenova/all-MiniLM-L6-v2'
});
console.log(result.vector); // Float32Array of embedding values
const results = await embedder.EmbedTexts({
texts: ['First text', 'Second text', 'Third text'],
model: 'Xenova/all-MiniLM-L6-v2'
});
console.log(results.vectors.length); // 3 embedding vectors
const result = await embedder.EmbedText({
text: 'Your text to embed',
model: 'onnx-community/embeddinggemma-2-ONNX',
dimensions: 256, // Matryoshka: keep the first 256 values, then re-normalize
maxInputTokens: 2048 // truncate longer inputs; this model's tokenizer declares no limit
});
dimensions larger than the model's output fails the call. Callers normally pass
MJ: Vector Indexes.Dimensions and MJ: AI Model Vendors.MaxInputTokens.
Following the BaseEmbeddings convention, a failed EmbedText returns vector: [] and a failed
EmbedTexts returns vectors: []. The error is logged. Check the length before using the result.
embedder.SetAdditionalSettings({
cacheDir: '/path/to/model/cache'
});
cacheDir applies when the runtime first loads, so set it before the first embed.
// Preload a model for faster first inference
await embedder.preloadModel('Xenova/all-mpnet-base-v2');
// Clear model cache to free memory
embedder.clearCache();
LocalEmbedding.clearSharedCache(); // Static method
| Variable | Default | Description |
|---|---|---|
TRANSFORMERS_CACHE_DIR |
./.cache/transformers |
Directory for storing downloaded models |
@huggingface/transformers (4.3.1 or later) is imported on the first embed, not when this package
loads. Importing it costs about 80–150 ms and 50 MB of memory (native onnxruntime and sharp), and
every process that loads the server class manifest loads this package.
Only one transformers.js runtime can live in a process: loading @xenova/transformers alongside it
aborts on duplicate native libraries. @memberjunction/search-engine's BGEReRanker uses the same
runtime for that reason.
Registered as LocalEmbedding via @RegisterClass(BaseEmbeddings, 'LocalEmbedding').
@memberjunction/ai - Core AI abstractions@memberjunction/global - Class registration@huggingface/transformers - Hugging Face Transformers.js runtime