NitroSQLite
Integrations

Vector search with sqlite-vec

Enable the optional sqlite-vec native build and use its typed helpers.

Vector search compares numeric arrays, often called embeddings, to find nearby matches. SQLite's virtual table mechanism lets an extension provide a table with its own storage and search behavior. sqlite-vec uses this mechanism for nearest-neighbor queries.

react-native-nitro-sqlite-vec is an optional companion package. Its native code is compiled into Nitro SQLite's library and registered with SQLite before a database opens. There is no runtime extension-loading step.

Install the companion alongside react-native-nitro-sqlite. Then enable the build on each platform you ship:

  • iOS: set NITRO_SQLITE_VEC=1 when installing Pods. The companion pod compiles sqlite-vec and the core pod enables its registration code.
  • Android: set nitroSqliteVec=true in android/gradle.properties. The core library compiles sqlite-vec's C sources and registration code.

Rebuild the native app after changing either flag. The companion package must be installed for the flag to resolve its source files. See the iOS and Android configuration pages for examples.

Create and search a vector table

import { open } from 'react-native-nitro-sqlite'
import {
  createVectorTable,
  isVecAvailable,
  knnSearch,
  vecVersion,
} from 'react-native-nitro-sqlite-vec'

const db = open({ name: 'vectors.sqlite' })

if (!isVecAvailable(db)) {
  db.close()
  throw new Error('Enable sqlite-vec in the native build')
}

console.log(vecVersion(db))
createVectorTable(db, 'embeddings', { dimensions: 3 })
db.execute('INSERT INTO embeddings (rowid, embedding) VALUES (?, ?)', [
  1,
  '[0.1, 0.2, 0.3]',
])

const matches = knnSearch(db, 'embeddings', [0.1, 0.2, 0.25], 10)
// Each match has rowid and distance.
db.close()

vecVersion(db) calls vec_version() and returns its version string. isVecAvailable(db) returns false if that call fails. createVectorTable(db, table, options) creates a vec0 virtual table if it does not exist. knnSearch(db, table, query, k, options?) returns an array of { rowid, distance } matches, ordered by distance; query can be a numeric array or a JSON vector string.

All four helpers are synchronous and take an open NitroSQLiteConnection:

ExportSignature
vecVersion(db: NitroSQLiteConnection) => string
isVecAvailable(db: NitroSQLiteConnection) => boolean
createVectorTable(db: NitroSQLiteConnection, table: string, options: CreateVectorTableOptions) => void
knnSearch(db: NitroSQLiteConnection, table: string, query: string | number[], k: number, options?: KnnSearchOptions) => KnnMatch[]

isVecAvailable() catches any error from vecVersion(), so false means its availability query failed, not necessarily that the build flag is absent. The other helpers let query errors propagate from db.execute().

CreateVectorTableOptions has dimensions: number, optional type: VectorColumnType, optional distanceMetric: VectorDistanceMetric, and optional column: string. VectorColumnType is 'float' | 'int8' | 'bit'; 'float' is the default. VectorDistanceMetric is 'L2' | 'cosine' | 'L1'; sqlite-vec's default is L2. The column defaults to 'embedding'. KnnSearchOptions has an optional column: string with the same default. For int8 and bit tables, construct vectors with sqlite-vec's vec_int8() and vec_bit() SQL functions as appropriate.

The package's five named type exports are VectorColumnType, VectorDistanceMetric, CreateVectorTableOptions, KnnSearchOptions, and KnnMatch. KnnMatch has rowid: number, distance: number, and a [column: string]: unknown index signature. The current knnSearch() helper selects only rowid and distance; write SQL through the core connection when you need more columns.

The helpers interpolate table and column identifiers into SQL. Only pass identifiers you control. They bind the query vector and k as parameters. The core query API can also run sqlite-vec SQL directly for features these small helpers do not wrap.