Swift-based vector database for on-device RAG using MLTensor and MLX Embedders
README
VecturaKit
VecturaKit is a Swift-based vector database designed for on-device apps through local vector storage and retrieval.
Inspired by Dripfarm's SVDB, VecturaKit uses MLTensor and swift-embeddings for generating and managing embeddings. It features Model2Vec support with the 32M parameter model as default for fast static embeddings, and supports NomicBERT, ModernBERT, RoBERTa, and XLM-RoBERTa models.
The framework offers VecturaKit as the core vector database with pluggable embedding providers. Use SwiftEmbedder for swift-embeddings integration, OpenAICompatibleEmbedder for hosted or local /v1/embeddings providers, NLContextualEmbedder for Apple's NaturalLanguage framework with zero external dependencies, or MLXEmbedder for Apple's MLX framework acceleration (available as a separate package).
It also includes CLI tools (vectura-cli and vectura-oai-cli) for easily trying out the package.
Model2Vec Support: Uses the retrieval 32M parameter Model2Vec model as default for fast static embeddings.
NomicBERT Support: Supports Nomic embedding models such as nomic-ai/nomic-embed-text-v1.5.
ModernBERT Support: Supports ModernBERT embedding models such as nomic-ai/modernbert-embed-base.
RoBERTa/XLM-RoBERTa Support: Supports models such as FacebookAI/roberta-base and FacebookAI/xlm-roberta-base.
Auto-Dimension Detection: Automatically detects embedding dimensions from models.
On-Device Storage: Stores and manages vector embeddings locally.
Hybrid Search: Combines vector similarity with BM25 text search for relevant search results (VecturaKit).
Pluggable Search Engines: Implement custom search algorithms by conforming to the VecturaSearchEngine protocol.
Batch Processing: Indexes documents in parallel for faster data ingestion.
Persistent Storage: Automatically saves and loads document data, preserving the database state across app sessions.
Configurable Search: Customizes search behavior with adjustable thresholds, result limits, and hybrid search weights.
Custom Storage Location: Specifies a custom directory for database storage.
Custom Storage Provider: Implements custom storage backends (SQLite, Core Data, cloud storage) by conforming to the VecturaStorage protocol.
Memory Management Strategies: Choose between automatic, full-memory, or indexed modes to optimize performance for datasets ranging from thousands to millions of documents. Learn more
MLX Support: GPU-accelerated embedding generation available via the separate VecturaMLXKit package.
OpenAI-Compatible Support: Connects to OpenAI-compatible /v1/embeddings endpoints exposed by local servers and hosted providers through OpenAICompatibleEmbedder.
NaturalLanguage Support: Uses Apple's NaturalLanguage framework for contextual embeddings with zero external dependencies through NLContextualEmbedder.
CLI Tools: Includes vectura-cli and vectura-oai-cli for database management and testing.
Supported Platforms
macOS 14.0 or later
iOS 17.0 or later
tvOS 17.0 or later
visionOS 1.0 or later
watchOS 10.0 or later
Installation
Swift Package Manager handles the distribution of Swift code and comes built into the Swift compiler.
To integrate VecturaKit into your project using Swift Package Manager, add the following dependency in your Package.swift file:
Note:VecturaNLKit and VecturaOAIKit are shipped from this package. The standalone VecturaOAIKit repository is intended to be deprecated after this integration lands. For MLX-based embeddings, see VecturaMLXKit.
Quick Start
Get up and running with VecturaKit in minutes. Here is an example of adding and searching documents:
import VecturaKit
Task{do{letconfig=VecturaConfig(name:"my-db")letembedder=SwiftEmbedder(modelSource:.default)letvectorDB=tryawaitVecturaKit(config: config, embedder: embedder)
// Add documents
letids=tryawait vectorDB.addDocuments(texts:["The quick brown fox jumps over the lazy dog","Swift is a powerful programming language"])
// Search documents
letresults=tryawait vectorDB.search(query:"programming language", numResults:5)print("Found \(results.count) results!")}catch{print("Error: \(error)")}}
Usage
Import VecturaKit
import VecturaKit
Create Configuration and Initialize Database
import Foundation
import VecturaKit
letconfig=VecturaConfig(
name:"my-vector-db",
directoryURL:nil, // Optional custom storage location
dimension:nil, // Auto-detect dimension from embedder (recommended)
searchOptions:VecturaConfig.SearchOptions(
defaultNumResults:10,
minThreshold:0.7,
hybridWeight:0.5, // Balance between vector and text search
k1:1.2, // BM25 parameters
b:0.75,
bm25NormalizationFactor:10.0))
// Create an embedder (SwiftEmbedder uses swift-embeddings library)
letembedder=SwiftEmbedder(modelSource:.default)letvectorDB=tryawaitVecturaKit(config: config, embedder: embedder)
💡 Tip: See the Indexed Storage Guide for detailed information on memory strategies and performance optimization for large-scale datasets.
📊 Performance: Check out the Performance Test Results for detailed benchmarking data and recommendations. For documentation index, see Docs/.
Add Documents
Single document:
lettext="Sample text to be embedded"letdocumentId=tryawait vectorDB.addDocument(
text: text,
id:UUID() // Optional, will be generated if not provided
)
VecturaKit allows you to implement your own storage backend by conforming to the VecturaStorage protocol. This is useful for integrating with different storage systems like SQLite, Core Data, or cloud storage.
Define a custom storage provider:
import Foundation
import VecturaKit
finalclassMyCustomStorageProvider:VecturaStorage{privatevardocuments:[UUID:VecturaDocument]=[:]func createStorageDirectoryIfNeeded()asyncthrows{
// Initialize your storage system
}func loadDocuments()asyncthrows->[VecturaDocument]{
// Load documents from your storage
returnArray(documents.values)}func saveDocument(_ document:VecturaDocument)asyncthrows{
// Save document to your storage
documents[document.id]= document
}func deleteDocument(withID id:UUID)asyncthrows{
// Delete document from your storage
documents.removeValue(forKey: id)}func updateDocument(_ document:VecturaDocument)asyncthrows{
// Update document in your storage
documents[document.id]= document
}func getTotalDocumentCount()asyncthrows->Int{
// Return total count (optional - protocol provides default implementation)
return documents.count
}}
Use the custom storage provider:
letconfig=VecturaConfig(name:"my-db")letcustomStorage=MyCustomStorageProvider()letvectorDB=tryawaitVecturaKit(
config: config,
storageProvider: customStorage
)
// Use vectorDB normally - all storage operations will use your custom provider
letdocumentId=tryawait vectorDB.addDocument(text:"Sample text")
VecturaStorage also provides default getDocument(id:) and documentExists(id:)
implementations. Custom providers can override them for more efficient single-document
lookups when their backend supports it.
Custom Search Engine
VecturaKit supports custom search engine implementations by conforming to the VecturaSearchEngine protocol. This allows you to implement specialized search algorithms (pure vector, pure text, custom hybrid, or other ranking methods).
Define a custom search engine:
import Foundation
import VecturaKit
structMyCustomSearchEngine:VecturaSearchEngine{func search(
query:SearchQuery,
storage:VecturaStorage,
options:SearchOptions)asyncthrows->[VecturaSearchResult]{
// Load documents from storage
letdocuments=tryawait storage.loadDocuments()
// Implement your custom search logic
// This example does a simple exact text match
guard case .text(let queryText)= query else{return[]}letresults= documents.filter{ doc in
doc.text.lowercased().contains(queryText.lowercased())}.map{ doc inVecturaSearchResult(
id: doc.id,
text: doc.text,
score:1.0,
createdAt: doc.createdAt
)}returnArray(results.prefix(options.numResults))}func indexDocument(_ document:VecturaDocument)asyncthrows{
// Optional: Update your search engine's internal index
}func removeDocument(id:UUID)asyncthrows{
// Optional: Remove from your search engine's internal index
}}
Use the custom search engine:
letconfig=VecturaConfig(name:"my-db")letembedder=SwiftEmbedder(modelSource:.default)letcustomEngine=MyCustomSearchEngine()letvectorDB=tryawaitVecturaKit(
config: config,
embedder: embedder,
searchEngine: customEngine
)
// All searches will use your custom search engine
letresults=tryawait vectorDB.search(query:"search query")
MLX Integration
For GPU-accelerated embeddings using Apple's MLX framework, see the separate VecturaMLXKit package. It provides MLXEmbedder, a drop-in VecturaEmbedder implementation, plus the vectura-mlx-cli command-line tool.
// Add both packages to your dependencies:
.package(url:"https://github.com/rryam/VecturaKit.git", from:"3.0.0"),.package(url:"https://github.com/rryam/VecturaMLXKit.git", from:"1.0.0"),
OpenAI-Compatible Integration
VecturaKit supports OpenAI-compatible embedding APIs through OpenAICompatibleEmbedder. This is useful for local servers such as Ollama, LM Studio, llama.cpp-compatible servers, vLLM, and hosted providers that expose /v1/embeddings.
Import OpenAI-Compatible Support
import VecturaKit
import VecturaOAIKit
Initialize Database with OpenAI-Compatible Embeddings
// Initialize with specific language
letembedder=tryawaitNLContextualEmbedder(
language:.spanish
)
// Get model information
letmodelInfo=await embedder.modelInfo
print("Language: \(modelInfo.language)")iflet dimension = modelInfo.dimension {print("Dimension: \(dimension)")}else{print("Dimension: Not yet determined")}
Add Documents
lettexts=["Natural language understanding is fascinating","Swift makes iOS development enjoyable","Machine learning on device preserves privacy"]letdocumentIds=tryawait vectorDB.addDocuments(texts: texts)
## What's Changed * Add VecturaOAIKit as a package target by @subsriram in https://github.com/rryam/VecturaKit/pull/81 **Full Changelog**: https://github.com/rryam/VecturaKit/compare/5.2.1...5.3.0
High
4/4/2026
Dependencies & License Audit
Loading dependencies...
Similar Packages
rag-news-summarizer📰 Fetch and summarize news articles locally using a Retrieval-Augmented Generation system powered by AI models for efficient information access.main@2026-04-21
mem9Enable AI agents to retain memory across sessions using persistent storage designed for continuous context retention.main@2026-04-21
HelixTransform Claude into a local AI assistant for Mac that controls apps, manages tasks, and remembers context across sessions.main@2026-04-21
consolidation-memoryStore, consolidate, and recall coding agent memories with provenance tracking using SQLite and FAISS for fast, structured knowledge access.main@2026-04-21
CodeRAGBuild semantic vector databases from code and docs to enable AI agents to understand and navigate your entire codebase effectively.main@2026-04-21