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

@photostructure/sqlite-vec

v1.1.1

Published

A vector search SQLite extension that runs anywhere - PhotoStructure's production-ready fork

Downloads

752

Readme

sqlite-vec

npm version Build & Test Memory Tests

[!NOTE] PhotoStructure's Production Fork: This is PhotoStructure's actively maintained fork of asg017/sqlite-vec, optimized for production use with additional features, comprehensive testing, and ongoing maintenance funded by PhotoStructure Inc.

Credits: Alex Garcia (original implementation), Vlad Lasky (community fork with 15+ merged upstream PRs), PhotoStructure Inc. (ongoing maintenance and improvements).

Why this fork exists:

  • PhotoStructure depends on sqlite-vec for production vector search in our photo management platform
  • We've added production-critical features, security hardening, and comprehensive testing
  • We're committed to maintaining this for as long as PhotoStructure exists
  • All improvements remain open source (MIT/Apache-2.0) for the community

Fork improvements:

  • Testing: AddressSanitizer/Valgrind/UBSan integration, 30+ error path tests, memory leak fixes
  • Security: Safe integer parsing, vendor checksum validation, pinned CI actions, OIDC releases
  • Node.js: Alpine/musl + Windows ARM64 prebuilds, bundled binaries (no post-install scripts)
  • Features: Distance constraints, OPTIMIZE command, ALTER TABLE RENAME, GLOB/LIKE operators
  • Documentation: Comprehensive error path coverage, KNN filtering behavior, production deployment guides

Maintained by PhotoStructure Inc. Contributions welcome. See CHANGELOG.md for detailed changes.

An extremely small, "fast enough" vector search SQLite extension that runs anywhere! A successor to sqlite-vss

  • Store and query float, int8, and binary vectors in vec0 virtual tables
  • Written in pure C, no dependencies, runs anywhere SQLite runs (Linux/MacOS/Windows, in the browser with WASM, Raspberry Pis, etc.)
  • Store non-vector data in metadata, auxiliary, or partition key columns

Installing

Node.js

Prebuilt binaries for all major platforms are published to npm:

npm install @photostructure/sqlite-vec

Supported platforms: Linux (x64, ARM64, musl), macOS (x64, ARM64), Windows (x64, ARM64)

Other Languages

For Python, Ruby, Rust, Go, and other language bindings, see the original asg017/sqlite-vec or Vlad Lasky's fork. This fork only publishes the Node.js package.

Electron

The native extension is automatically resolved from app.asar.unpacked when running inside a packaged Electron app. You need to configure your build tool to unpack the extension binaries:

electron-builder:

{
  "asarUnpack": ["node_modules/@mceachen/sqlite-vec/**/*.{so,dylib,dll}"]
}

electron-forge:

packagerConfig: {
  asar: {
    unpack: "*.{so,dylib,dll}";
  }
}

What's New

See CHANGELOG.md for a complete list of improvements, bug fixes, and merged upstream PRs.

Basic Usage

Vector types: sqlite-vec supports three vector types with different trade-offs:

-- Float vectors (32-bit floating point, most common)
CREATE VIRTUAL TABLE vec_floats USING vec0(embedding float[384]);

-- Int8 vectors (8-bit integers, smaller memory footprint)
CREATE VIRTUAL TABLE vec_int8 USING vec0(embedding int8[384]);

-- Binary vectors (1 bit per dimension, maximum compression)
CREATE VIRTUAL TABLE vec_binary USING vec0(embedding bit[384]);

Usage example:

.load ./vec0

create virtual table vec_examples using vec0(
  sample_embedding float[8]
);

-- vectors can be provided as JSON or in a compact binary format
insert into vec_examples(rowid, sample_embedding)
  values
    (1, '[0.279, -0.95, -0.45, -0.554, 0.473, 0.353, 0.784, -0.826]'),
    (2, '[-0.156, -0.94, -0.563, 0.011, -0.947, -0.602, 0.3, 0.09]'),
    (3, '[-0.559, 0.179, 0.619, -0.987, 0.612, 0.396, -0.319, -0.689]'),
    (4, '[0.914, -0.327, -0.815, -0.807, 0.695, 0.207, 0.614, 0.459]'),
    (5, '[0.072, 0.946, -0.243, 0.104, 0.659, 0.237, 0.723, 0.155]'),
    (6, '[0.409, -0.908, -0.544, -0.421, -0.84, -0.534, -0.798, -0.444]'),
    (7, '[0.271, -0.27, -0.26, -0.581, -0.466, 0.873, 0.296, 0.218]'),
    (8, '[-0.658, 0.458, -0.673, -0.241, 0.979, 0.28, 0.114, 0.369]'),
    (9, '[0.686, 0.552, -0.542, -0.936, -0.369, -0.465, -0.578, 0.886]'),
    (10, '[0.753, -0.371, 0.311, -0.209, 0.829, -0.082, -0.47, -0.507]'),
    (11, '[0.123, -0.475, 0.169, 0.796, -0.201, -0.561, 0.995, 0.019]'),
    (12, '[-0.818, -0.906, -0.781, 0.255, 0.584, -0.156, -0.873, -0.237]'),
    (13, '[0.992, 0.058, 0.942, 0.722, -0.977, 0.441, 0.363, 0.074]'),
    (14, '[-0.466, 0.282, -0.777, -0.13, -0.093, 0.908, 0.752, -0.473]'),
    (15, '[0.001, -0.643, 0.825, 0.741, -0.403, 0.278, 0.218, -0.694]'),
    (16, '[0.525, 0.079, 0.557, 0.061, -0.999, -0.352, -0.961, 0.858]'),
    (17, '[0.757, 0.663, -0.385, -0.884, 0.756, 0.894, -0.829, -0.028]'),
    (18, '[-0.862, 0.521, 0.532, -0.743, -0.049, 0.1, -0.47, 0.745]'),
    (19, '[-0.154, -0.576, 0.079, 0.46, -0.598, -0.377, 0.99, 0.3]'),
    (20, '[-0.124, 0.035, -0.758, -0.551, -0.324, 0.177, -0.54, -0.56]');


-- Find 3 nearest neighbors using LIMIT
select
  rowid,
  distance
from vec_examples
where sample_embedding match '[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]'
order by distance
limit 3;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 5     │ 1.16368770599365 │
│ 13    │ 1.75137972831726 │
│ 11    │ 1.83941268920898 │
└───────┴──────────────────┘
*/

How vector search works: The MATCH operator finds vectors similar to your query vector. In the example above, sample_embedding MATCH '[0.5, ...]' searches for vectors closest to [0.5, ...] and returns them ordered by distance (smallest = most similar).

Under the hood, sqlite-vec stores vectors in fixed-size chunks and scans each chunk to find the top-K nearest results, using SIMD instructions (AVX on x86_64, NEON on ARM) to accelerate distance calculations. Results from each chunk are merged using a two-pointer technique to produce the final sorted output. This brute-force approach trades theoretical optimality for simplicity and reliability — no complex index structures to maintain or tune.

Note: All vector similarity queries require LIMIT or k = ? (where k is the number of nearest neighbors to return). This prevents accidentally returning too many results on large datasets, since finding all vectors within a distance threshold requires calculating distance to every vector in the table.

Advanced Usage

This fork adds several powerful features for production use:

Distance Constraints for KNN Queries

Filter results by distance thresholds using >, >=, <, <= operators on the distance column:

-- KNN query with distance constraint
-- Requests k=10 neighbors, but only returns those with distance < 1.5
select rowid, distance
from vec_examples
where sample_embedding match '[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]'
  and k = 10
  and distance < 1.5
order by distance;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 5     │ 1.16368770599365 │
└───────┴──────────────────┘
*/

-- KNN query with range constraint: find vectors in a specific distance range
select rowid, distance
from vec_examples
where sample_embedding match '[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]'
  and k = 20
  and distance between 1.5 and 2.0
order by distance;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 13    │ 1.75137972831726 │
│ 11    │ 1.83941268920898 │
│ 7     │ 1.89339029788971 │
│ 8     │ 1.92658650875092 │
│ 10    │ 1.93983662128448 │
└───────┴──────────────────┘
*/

Cursor-based Pagination

Instead of using OFFSET (which is slow for large datasets), you can use the last result's distance value as a 'cursor' to fetch the next page. This is more efficient because you're filtering directly rather than skipping rows.

-- First page: get initial results
select rowid, distance
from vec_examples
where sample_embedding match '[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]'
  and k = 3
order by distance;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 5     │ 1.16368770599365 │
│ 13    │ 1.75137972831726 │
│ 11    │ 1.83941268920898 │
└───────┴──────────────────┘
*/

-- Next page: use last distance as cursor (distance > 1.83941268920898)
select rowid, distance
from vec_examples
where sample_embedding match '[0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]'
  and k = 3
  and distance > 1.83941268920898
order by distance;
/*
┌───────┬──────────────────┐
│ rowid │     distance     │
├───────┼──────────────────┤
│ 7     │ 1.89339029788971 │
│ 8     │ 1.92658650875092 │
│ 10    │ 1.93983662128448 │
└───────┴──────────────────┘
*/

Space Reclamation with Optimize

optimize compacts vec shadow tables. To shrink the database file:

-- Before creating vec tables: enable autovacuum and apply it (recommended)
PRAGMA auto_vacuum = FULL;  -- or INCREMENTAL
VACUUM;                     -- activates the setting

-- Use WAL for better concurrency
PRAGMA journal_mode = WAL;

After deletes, reclaim space:

-- Compact shadow tables
INSERT INTO vec_examples(vec_examples) VALUES('optimize');

- Flush WAL
PRAGMA wal_checkpoint(TRUNCATE);

-- Reclaim freed pages (if using auto_vacuum=INCREMENTAL)
PRAGMA incremental_vacuum;

-- If you did NOT enable autovacuum, run VACUUM (after checkpoint) to shrink the file.
-- With autovacuum on, VACUUM is optional.
VACUUM;

VACUUM should not corrupt vec tables; a checkpoint first is recommended when using WAL so the rewrite starts from a clean state.

Sponsors

[!NOTE] The sponsors listed below support the original asg017/sqlite-vec project by Alex Garcia, not this community fork.

Development of the original sqlite-vec is supported by multiple generous sponsors! Mozilla is the main sponsor through the new Builders project.

sqlite-vec is also sponsored by the following companies:

As well as multiple individual supporters on Github sponsors!

If your company interested in sponsoring sqlite-vec development, send me an email to get more info: https://alexgarcia.xyz

Documentation

For full API reference and guides, see the upstream sqlite-vec documentation.

See Also

  • sqlite-ecosystem, Maybe more 3rd party SQLite extensions I've developed
  • sqlite-rembed, Generate text embeddings from remote APIs like OpenAI/Nomic/Ollama, meant for testing and SQL scripts
  • sqlite-lembed, Generate text embeddings locally from embedding models in the .gguf format