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
- Specification — file format, architecture, design decisions
- API Reference — complete Python API, filter operators, aggregation
- Language Bindings — C, C++, Node.js, Go, Java, C#
- Building & Testing — toolchain setup for every language
- bench_native.py — Python vs Rust head-to-head benchmark
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 |
43 |
| Node.js | koffi FFI (pure JS, no native compile) |
bindings/node/ |
22 |
| Go | cgo + C header | bindings/go/ |
23 |
| Java | Foreign Function & Memory API (JDK 22+) | bindings/java/ |
31 |
| C# | P/Invoke + DllImport |
bindings/csharp/ |
32 |
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.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| moofile-1.0.1-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.1-cp314-cp314-macosx_11_0_arm64.whl | CPython 3.14 | CPython 3.14 | macOS 11.0+ ARM64 | Details |
| moofile-1.0.1-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
| moofile-1.0.1-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.1-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.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | moofile-1.0.1-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 |
9db813358ad332c61a26754a2af935c6bcdc9c6589f3797a167ba0970a1ea5da
|
|
BLAKE2b-256 checksum How to use checksums |
1e3114247e45866eb0a3fd67602213854323cfea0a0c815b25aa5e037546b4ab
|
| 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 logRelease files / moofile-1.0.1-cp314-cp314-macosx_11_0_arm64.whl
| Download URL | moofile-1.0.1-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 |
0e09b50fd8eda974fdcc93ab1318f0b62530391f2592a545d61040d6719b1f83
|
|
BLAKE2b-256 checksum How to use checksums |
539beedc871c65302ac3174cf8e11d7e9f09842327509b07a89bd206ff775974
|
| 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 logRelease files / moofile-1.0.1-cp312-cp312-win_amd64.whl
| Download URL | moofile-1.0.1-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
569338046d876b63172228ab862fc9e33ed9408bfff6f2c1997f71bd75a44efe
|
|
BLAKE2b-256 checksum How to use checksums |
2471335bb5c0eee3b273e5e8866694c9e0068a4320afca57ba3c6683192cca94
|
| 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 logRelease files / moofile-1.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | moofile-1.0.1-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 |
d4c9339b6958a77234a3e5f29c2c8962aea084a0a2878ef75dc61d633677b81c
|
|
BLAKE2b-256 checksum How to use checksums |
8c473245e60fce1703e4d4f374d4c1de8c53ee006733975e7accef7f106dcd86
|
| 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 logRelease files / moofile-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | moofile-1.0.1-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 |
85059a8ed1c716cd2dbfd1c73970b0d457ddcd12cf54270d1aa4c59e102eaa5d
|
|
BLAKE2b-256 checksum How to use checksums |
891de5c51aeee90392b723b4a74ed719e2f00bd48a64c775c229b3b093c3e0c3
|
| 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