LocalMode
Transformers

Image Features

Extract feature vectors for image similarity search with SigLIP.

Extract dense feature vectors from images using SigLIP models. These vectors enable image similarity search, duplicate detection, and cross-modal (text-to-image) search.

For full API reference (extractImageFeatures(), options, result types, and custom providers), see the Core Vision guide.

See it in action

Try the Photo Search block — its Duplicates tab groups near-duplicates with a tunable similarity threshold, alongside image-to-image similarity search over the same in-browser vector space.

ModelSizeDimensionsUse Case
Xenova/siglip-base-patch16-224~400MB768Image search, text-to-image matching
onnx-community/dinov2-base-ONNX~350MB768Self-supervised image features, similarity

SigLIP models encode both images and text into the same vector space, enabling text-to-image search. Use transformers.imageFeatures() for images and transformers.embedding() with the same model for text queries.

Duplicate Detection Example

Based on the Photo Search block:

import { transformers } from '@localmode/transformers';
import { extractImageFeatures, cosineSimilarity } from '@localmode/core';

const model = transformers.imageFeatures('Xenova/siglip-base-patch16-224');
const SIMILARITY_THRESHOLD = 0.85;

async function findDuplicates(images: string[]) {
  // Extract features for all images
  const allFeatures: Float32Array[] = [];
  for (const img of images) {
    const { features } = await extractImageFeatures({
      model,
      image: img,
      abortSignal: controller.signal,
    });
    allFeatures.push(features);
  }

  // Compare all pairs
  const duplicates: [number, number, number][] = [];
  for (let i = 0; i < allFeatures.length; i++) {
    for (let j = i + 1; j < allFeatures.length; j++) {
      const similarity = cosineSimilarity(allFeatures[i], allFeatures[j]);
      if (similarity > SIMILARITY_THRESHOLD) {
        duplicates.push([i, j, similarity]);
      }
    }
  }

  return duplicates;
}

Semantic Image Search with VectorDB

Based on the Photo Search block:

import { createVectorDB, embed, extractImageFeatures } from '@localmode/core';
import { transformers } from '@localmode/transformers';

const imageModel = transformers.imageFeatures('Xenova/siglip-base-patch16-224');
const textModel = transformers.embedding('Xenova/siglip-base-patch16-224');

const db = await createVectorDB({
  name: 'gallery',
  dimensions: 768,
  storage: 'memory',
});

// Index images by their features
async function indexImage(id: string, imageDataUrl: string) {
  const { features } = await extractImageFeatures({
    model: imageModel,
    image: imageDataUrl,
  });
  await db.add({ id, vector: features, metadata: { fileName: id } });
}

// Search by text query (cross-modal)
async function searchByText(query: string, topK = 10) {
  const { embedding } = await embed({ model: textModel, value: query });
  return db.search(embedding, { k: topK });
}

Best Practices

Image Features Tips

  1. Use SigLIP for search — SigLIP vectors work across text and images in the same space
  2. Store in VectorDB — Use createVectorDB with storage: 'memory' for fast search
  3. Cosine similarity — Use cosineSimilarity() from core to compare feature vectors
  4. 768 dimensions — SigLIP-Base produces 768-dimensional vectors

Composed Block

BlockDescriptionLinks
Image SearchText→image and image→image CLIP search over your photo library with a top-K slider and similarity thresholdLive · Install: npx shadcn add @localmode/ui/blocks/photo/image-search

Next Steps

On this page