Skip to content

Swift / iOS support: native binding over the TurboVec core #28

Description

@Davidobot

Summary

Make LodeDB usable from Swift on iOS. The Python package does not run on iOS (no Python runtime, and App Review guideline 2.5.2 disallows downloading or executing code that changes app functionality), so this is a native Swift/Rust product, not a port of the Python layer.

The portable asset is the vendored Rust TurboVec core (third_party/turbovec): MIT, 64-bit only, with aarch64/NEON kernels (encode.rs, search.rs), Accelerate-backed BLAS, and a little-endian on-disk format (io.rs, TVIM v3). iOS devices are arm64, so the core compiles and runs on-device, and .tvim files are byte-compatible across platforms (an index built on a server loads on the phone).

What ports vs what does not

Ports: the TurboVec core (scan, quantize, format).

Does not port as-is: the Python engine (commit/delta/WAL, BM25, filters, core.py), the sentence-transformers/PyTorch embedding stack, the CUDA and PyTorch-MPS paths, and the CLI/server/MCP/adapters.

The cleanest long-term route is to share the engine through the native lodedb-core crate (#27) and add a Swift binding over it, rather than reimplementing the engine in Swift. The vector-only MVP below can ship before that lands.

Staged approach

  1. Vector-only MVP. Add a staticlib plus C ABI shim (or UniFFI) over the TurboVec core, add an ios arm to turbovec/build.rs so it links framework=Accelerate on iOS (or falls back to the pure-Rust matmul, which only affects the one-time rotation-matrix build, not the hot scan), build for aarch64-apple-ios and aarch64-apple-ios-sim, package an LodeDB.xcframework, and wrap it in a Swift class exposing openVectorStore, addVector, search, remove, get, persist. The app supplies vectors. This reuses the existing vector-only path (open_vector_store, add_vectors, search_by_vector in src/lodedb/local/db.py).
  2. Durable storage and metadata filters in the binding. Atomic temp-file-rename persistence, and the metadata filter predicate compiled to the boolean mask that search_with_mask already consumes. Full delta/WAL parity only if on-device commit latency demands it.
  3. On-device text embedding via ONNX. The repo embeds through sentence-transformers on PyTorch today, which cannot ship on iOS. Adopt ONNX as a first-class embedding backend: export the preset models (MiniLM 384-d, BGE 768-d) to ONNX and run them through ONNX Runtime Mobile on iOS (optionally with the Core ML execution provider to reach the Neural Engine) and through onnxruntime on desktop. This gives one model artifact and one runtime across platforms instead of a per-model Core ML conversion. The embedding contract must match exactly (mean pooling plus L2 normalization, BGE query prefix, max_seq_length, output dim) along with the persisted embedder-identity and dim guard, or recall silently degrades. Tokenization can reuse the Rust tokenizers crate if it lives in lodedb-core (Consolidate the engine into a native lodedb-core crate with thin language bindings #27).
  4. Optional Metal scan, only if on-device benchmarks show NEON CPU is the bottleneck. CUDA is irrelevant on iOS and the existing PyTorch-MPS scan is documented as slower than NEON, so NEON CPU is the default.

Out of scope

CLI, dev server, MCP server, the lodedb doctor model-download flow, and the LangChain/LlamaIndex/mem0/PrivateGPT adapters. iOS apps call the Swift wrapper directly.

Notes

  • Licensing: TurboVec is MIT and the LodeDB patches are Apache-2.0, both fine for static linking in an App Store binary if the notices are preserved. "LodeDB" and "Egoist Machines" are trademarks; Apache grants no trademark rights.
  • Budget for app binary size (a bundled embedding model is tens of MB), on-device corpus size and memory (the scan is exact and O(n)), and battery and thermals for repeated parallel scans.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions