Embeddings
Hooks for text embedding and semantic search.
Embedding Hooks
See it in action
Try the Knowledge Base block and Photo Search block for working demos of these hooks.
useEmbed
Embed a single text value.
import { useEmbed } from '@localmode/react';
import { transformers } from '@localmode/transformers';
const model = transformers.embedding('Xenova/all-MiniLM-L6-v2');
function Demo() {
const { data, isLoading, error, execute } = useEmbed({ model });
return (
<div>
<button onClick={() => execute('Hello world')}>Embed</button>
{data && <p>Vector dimensions: {data.embedding.length}</p>}
</div>
);
}Returns { embedding: Float32Array, usage: { tokens }, response: { modelId, timestamp } }.
useEmbedMany
Embed multiple values in batch.
import { useEmbedMany } from '@localmode/react';
const { data, isLoading, execute } = useEmbedMany({ model });
await execute(['Hello', 'World', 'Foo', 'Bar']);
// data.embeddings = [Float32Array, Float32Array, ...]useSemanticSearch
Combines embedding and vector DB search in one hook. A hook-level metadata filter and similarity threshold apply to every search, and each can be overridden per call.
import { useSemanticSearch } from '@localmode/react';
import { transformers } from '@localmode/transformers';
import { createVectorDB } from '@localmode/core';
const model = transformers.embedding('Xenova/all-MiniLM-L6-v2');
const db = await createVectorDB({ name: 'notes', dimensions: 384 });
function SearchDemo() {
const { results, isSearching, usage, search, reset } = useSemanticSearch({
model,
db,
topK: 10,
filter: { category: 'docs' },
threshold: 0.4,
});
return (
<div>
<input onChange={(e) => search(e.target.value)} />
{results.map((r) => (
<div key={r.id}>{r.content} (score: {r.score.toFixed(2)})</div>
))}
{usage && <small>{usage.embeddingTokens} tokens · {usage.searchDurationMs}ms search</small>}
</div>
);
}Options
| Option | Type | Description |
|---|---|---|
model | EmbeddingModel | The embedding model to use (required) |
db | SemanticSearchDB | The vector database to search (required) |
topK | number | Number of results to return (default: 10) |
filter | Record<string, unknown> | Metadata filter applied to every search |
threshold | number | Minimum similarity threshold for results |
Per-Call Overrides
search(query, options?) accepts SemanticSearchCallOptions — per-call filter, threshold, and topK that override the hook-level values for that call only:
await search('find documents about privacy'); // hook-level filter
await search('blog posts only', { filter: { category: 'blog' } }); // per-call override
await search('strict match', { threshold: 0.7, topK: 3 });Return Value
| Property | Type | Description |
|---|---|---|
results | Array<{ id, content, metadata, score }> | Search results from the last query |
isSearching | boolean | Whether a search is currently running |
error | Error | null | Error from the last failed search |
usage | SemanticSearchUsage | null | { embeddingTokens, embedDurationMs, searchDurationMs } from the last completed search (null until one completes) |
search | (query, options?) => Promise<void> | Execute a search, optionally overriding filter/threshold/topK |
reset | () => void | Reset results, usage, and error state |
For full API reference on embed() and semanticSearch(), see the Core Embeddings guide. For recommended models, see the Transformers Embeddings guide.
useEmbedImage
Embed a single image into the same vector space as text using CLIP/SigLIP models for cross-modal search.
import { useEmbedImage } from '@localmode/react';
import { transformers } from '@localmode/transformers';
const model = transformers.clipEmbedding('Xenova/clip-vit-base-patch32');
const { data, execute } = useEmbedImage({ model });
await execute(imageDataUrl);
// data.embedding = Float32Array(512) — same space as text embeddingsuseEmbedManyImages
Batch image embedding for indexing image collections, with progress tracking (streams via streamEmbedManyImages(), mirroring useEmbedMany).
import { useEmbedManyImages } from '@localmode/react';
const { data, progress, execute } = useEmbedManyImages({ model, batchSize: 8 });
await execute([imageUrl1, imageUrl2, imageUrl3]);
// progress = { completed: 3, total: 3 }
// data.embeddings = [Float32Array, Float32Array, Float32Array]useReindex
Re-embed all documents in a VectorDB with a new embedding model. Wraps reindexCollection() with progress tracking, cancellation, and a result summary.
import { useReindex } from '@localmode/react';
const { isReindexing, progress, result, error, reindex, cancel } = useReindex({
db: vectorDB,
model: transformers.embedding('Xenova/bge-small-en-v1.5'), // the new model
batchSize: 50,
});
// While running: progress = { completed, total, phase }
// After completion: result holds the ReindexResult of the last successful run
// (null until one completes; cleared when a new run starts)
await reindex();For multimodal embedding details, see Multimodal Embeddings. For drift detection, see Embedding Drift Detection.
Blocks
| App | Description | Links |
|---|---|---|
| Knowledge Base (Semantic Search) | Full-text semantic search with useSemanticSearch | Live block · Source |
| Photo Search (Product Search) | Product catalog search with useSemanticSearch | Live block · Source |