Skip to main content

MooFile

MooFile

A lightweight, embedded, single-file document store with a developer-friendly query API.
No server. No infrastructure. Just a file and a library.
🦀 Rust core available — 2-24× faster than pure Python.
🧠 On-device autoembedding — local embedding models for semantic search.
🔀 Multi-process friendly — a background worker and a web app can share one file.

from moofile import Collection, count, mean

with Collection("mydata.bson", 
                indexes=["email", "age"],
                vector_indexes={"embedding": 1024},
                text_indexes=["content"],
                auto_embed={
                    "content": {
                        "model": "hf:jsonMartin/voyage-4-nano-gguf:voyage-4-nano-q8_0.gguf",
                        "target": "embedding",
                        "precision": "int8",
                    },
                }) as db:
    
    # Insert — auto-embeds content into embedding (int8, 1KB/doc)
    db.insert({
        "name": "Alice", 
        "email": "alice@example.com", 
        "age": 30,
        "content": "Machine learning and data science expert",
    })

    # Traditional query
    results = db.find({"age": {"$gt": 25}}).sort("age").to_list()
    
    # Vector similarity search (raw vector)
    similar = db.find({}).vector_search("embedding", query_vector, limit=5).to_list()
    
    # Semantic search — auto-embeds query text
    similar = db.find({}).semantic("content", "data science", limit=5).to_list()
    
    # BM25 text search
    text = db.find({}).text_search("content", "machine learning", limit=10).to_list()
    
    # Hybrid search — auto-embeds query vector from query text
    results = db.find({}).hybrid_search("content", "content", "data science", None, 10).to_list()

Why MooFile?

SQLite JSON file MongoDB MooFile
No server
Document-oriented
Indexes
Vector search ✓ (Atlas)
On-device autoembedding
Text search ✓ (FTS)
Developer API ✗ (SQL) ✓ (raw)
Single-file portable
Multi-process safe ✓ (v0.5.2+)
Rust core available ✓ (v0.3+)

Target dataset size: megabytes to single-digit gigabytes.


Sharing a file between processes

Like SQLite, several processes can keep the same file open — the usual setup being a long-running worker that writes and a web app that reads:

# worker.py — writes events forever
with Collection("app.bson", indexes=["kind"]) as db:
    for event in stream:
        db.insert({"kind": "event", **event})

# web.py — reads them, and writes the occasional setting
with Collection("app.bson", indexes=["kind"]) as db:
    recent = db.find({"kind": "event"}).sort("_id", descending=True).limit(50).to_list()
    db.insert({"kind": "config", "theme": "dark"})

Readers pick up new writes automatically, writes are serialized so nothing is lost or interleaved, and duplicate _ids are caught across processes. Best suited to one writer with many readers — writes take a brief exclusive lock, so many simultaneous writers will queue.


Installation

pip install moofile

This installs the pure-Python version which works everywhere. See Native install below for the Rust-powered version.


Quick Start

from datetime import datetime, timezone
from bson import Binary

from moofile import Collection

db = Collection("users.bson", 
                indexes=["email", "status"],
                text_indexes=["bio"],
                vector_indexes={"profile_vec": 128})

# Insert — any BSON type: datetimes, binary, ObjectId, Decimal128, nested docs
alice = db.insert({"name": "Alice", "email": "a@ex.com", "age": 30, "status": "active",
                   "joined": datetime(2025, 1, 15, tzinfo=timezone.utc),
                   "avatar": Binary(b"...")})
db.insert_many([...])

# Query — ranges work on dates too
active = db.find({"status": "active"}).to_list()
young  = db.find({"age": {"$lt": 30}}).sort("age").to_list()
recent = db.find({"joined": {"$gte": datetime(2025, 1, 1, tzinfo=timezone.utc)}}).to_list()
one    = db.find_one({"email": "alice@example.com"})

# Vector search
similar = db.find({}).vector_search("profile_vec", query_vector, limit=3).to_list()
for doc, score in similar:
    print(f"{doc['name']}: {score:.3f}")

# Text search
results = db.find({}).text_search("bio", "machine learning", limit=5).to_list()

# Update & Delete
db.update_one({"email": "a@ex.com"}, set={"age": 31})
db.update_many({"status": "trial"}, set={"status": "expired"})
db.delete_one({"email": "c@ex.com"})
db.delete_many({"status": "expired"})

With Autoembedding

from moofile import Collection

# Autoembedding: text in "abstract" is automatically embedded into
# "embedding" on insert, using a local GGUF model (downloaded on first use).
db = Collection("papers.bson",
    indexes=["year", "category"],
    vector_indexes={"embedding": 1024},
    auto_embed={
        "abstract": {
            "model": "hf:jsonMartin/voyage-4-nano-gguf:voyage-4-nano-q8_0.gguf",
            "target": "embedding",
            "dims": 1024,
            "precision": "int8",
        },
    })

# Insert — auto-embeds abstract → embedding (1 KB, int8 quantized)
db.insert({"title": "Quantum ML", "abstract": "Quantum computing for ML...", "year": 2025})

# Semantic search — query text is auto-embedded using the same model
results = db.find({"year": 2025}).semantic("abstract", "quantum algorithms", 5).to_list()
for doc, score in results:
    print(f"{doc['title']}: {score:.3f}")

# Hybrid search — auto-embeds query_text for the vector leg
results = db.find({}).hybrid_search("abstract", "abstract", "quantum", None, 10).to_list()

Native Install (Rust Core)

When the Rust native extension is installed, import moofile transparently uses it — same API, 2-24× faster.

From source (requires Rust)

# Install Rust: https://rustup.rs
curl --proto '=https' --tls v1.2 -sSf https://sh.rustup.rs | sh

# Build and install with native extension
pip install maturin
cd moofile
maturin develop --release

Prebuilt wheels

Coming soon — GitHub Actions CI will build platform wheels for:

Platform Architectures
Linux x86_64 (manylinux)
macOS x86_64, ARM64 (Apple Silicon)
Windows x86_64

In the meantime, pip install moofile always works (pure Python fallback).


CLI Tools

Tool Description
moosh Interactive Python shell with db pre-bound
moo2json Export/import to/from JSON
moo2mongo Export/import to/from MongoDB
moo2sqlite Export/import to/from SQLite
moosh users.bson --indexes email,age
moo2json users.bson users.json
moo2json --import users.json users.bson --indexes email
moo2mongo users.bson --uri mongodb://localhost/mydb --collection users
moo2sqlite users.bson users.db --table people

Full Documentation


Language Bindings

MooFile is implemented in Rust with a Python binding (via PyO3). A C shared library (libmoofile.so) exposes the full API via extern "C" functions, and all other languages consume that:

Language Approach Directory Tests
Python PyO3 native (or pure-Python fallback) bindings/python/ 307
C extern "C" from Rust core bindings/c/ 73
C++ RAII wrapper over C API bindings/c/include/moofile.hpp 42
Node.js koffi FFI (pure JS, no native compile) bindings/node/ 22
Go cgo + C header bindings/go/ 22
Java Foreign Function & Memory API (JDK 22+) bindings/java/ 30
C# P/Invoke + DllImport bindings/csharp/ 30

Plus 8 cross-backend parity scenarios comparing pure-Python, PyO3 and C.

Every binding passes documents as JSON strings across the FFI boundary. The autoembedding feature (local GGUF embedding models) works transparently in all languages — the model loading and inference happen entirely inside the Rust core.

See bindings/README.md for build instructions, usage examples, and test results for each language.


Development

Setting up a machine from scratch — including the toolchains for all seven language bindings — is covered in BUILDING.md. Once installed, ./scripts/test-all.sh runs every suite and prints a summary, skipping any language whose toolchain is absent.

# Unit tests (PYTHONPATH=. so you test this checkout, not an installed copy)
PYTHONPATH=. pytest tests/ -v

# Cross-implementation tests — runs both backends
PYTHONPATH=. pytest tests-cross/ -v

# Rust core tests
export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1
cd core && cargo test

# Rust benchmark
cd core && cargo run --example bench --release

# Python vs Rust benchmark
PYTHONPATH=. python bench_native.py

Project layout

moofile/
├── core/                    # Rust engine (cargo build)
│   ├── src/{lib,storage,index,query,text,cache,embed,errors}.rs
│   └── examples/bench.rs    # Pure-Rust benchmark
├── bindings/                # Language bindings — see bindings/README.md
│   ├── python/              # PyO3 binding (maturin build)
│   ├── c/                   # C ABI (cdylib) + C++ header-only wrapper
│   ├── node/                # Node.js via koffi
│   ├── go/                  # Go via cgo
│   ├── java/                # Java via the Foreign Function & Memory API
│   └── csharp/              # C# via P/Invoke
├── moofile/                 # Python package
│   ├── __init__.py          # Auto-detects Rust, falls back to Python
│   ├── _rust_adapter.py     # Adapts Rust NativeCollection → Python API
│   ├── collection.py        # Pure-Python reference implementation
│   ├── query.py, index.py, storage.py, ...
│   └── cli/                 # moosh, moo2json, moo2mongo, moo2sqlite
├── tests/                   # Python test suite
├── tests-cross/             # Cross-implementation validation
├── docs/README.md           # Full Python API reference
├── moofile-spec.md          # File format & architecture spec
└── pyproject.toml           # Python package config

Other languages

Beyond Python, MooFile ships bindings for C, C++, Node.js, Go, Java and C#, all layered on one C ABI (bindings/c). They share the same file format, query language and semantics.

cargo build -p moofile-c --release   # build the shared library first

See bindings/README.md for per-language setup, usage, and the ABI contract (error conventions, ownership rules, no-match semantics).


License

MIT — see LICENSE.

Release files for moofile 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for moofile 1.0.0
File
moofile-1.0.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.17+ x86-64 Details
moofile-1.0.0-cp314-cp314-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 macOS 11.0+ ARM64 Details
moofile-1.0.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
moofile-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.17+ x86-64 Details
moofile-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details

Total release size: 16.9 MB

Release files / moofile-1.0.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL moofile-1.0.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.5 MB
Tags CPython 3.14 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
4481b775f6077fb9e6b9cbb479dea2af17c5d2d2b6c72f1d5b39e51f8e48952c
BLAKE2b-256 checksum
How to use checksums
d22239c97b915d6c4e32af4d0e39b3f9422d4bc0ae9d42c28b9876c6ff038d81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / moofile-1.0.0-cp314-cp314-macosx_11_0_arm64.whl

Download URL moofile-1.0.0-cp314-cp314-macosx_11_0_arm64.whl
Size 3.2 MB
Tags CPython 3.14 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
96bf14e293d356ff742d14915d5d9909b2cc24a10713a9d8f2973c062c7efc31
BLAKE2b-256 checksum
How to use checksums
584b50c975989e1df423af273103301d3e656776dd7bf7c0f89fbcbb6980adec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / moofile-1.0.0-cp312-cp312-win_amd64.whl

Download URL moofile-1.0.0-cp312-cp312-win_amd64.whl
Size 3.1 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
f0e56dff2cf8769af0d6c8e4d27efbe6396e486f5fecdcf112c943c298b461f3
BLAKE2b-256 checksum
How to use checksums
eecefe752683612ae7d0ce3a51ea9863ee1cc2f6dda2504e793663aafc00e654
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / moofile-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL moofile-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.5 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
475b5afb208a4851f904ae1215ad62de336157c842eb0e3500b830ed11e29497
BLAKE2b-256 checksum
How to use checksums
4829011414f3f8714c2ea2759fac0507374a39933ee2e10640cee25339b5bde8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / moofile-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL moofile-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.5 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
1830408b7e786633a2d09a65570cc2305d03bea1647d41b2a6b506daa274f3b6
BLAKE2b-256 checksum
How to use checksums
fb970a1ea29860874b40ad064873114a3ea8e5d39767ff19b18caca66313372b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page