Rust
Rust client for ChronDB, a time-traveling key/value database built on Git architecture.
Requirements
Rust 1.56+ (2021 edition)
libclang(for bindgen to generate FFI bindings)
Stack Size (Handled Automatically)
ChronDB uses GraalVM native-image with Apache Lucene and JGit, which require deep call stacks (~64MB).
This is handled automatically. The Rust binding spawns a dedicated worker thread with a 64MB stack for all FFI operations. You do not need to configure RUST_MIN_STACK, ulimit, or any other stack settings.
The worker thread architecture also provides:
Consistent stack size across all platforms
No special CI configuration required
Thread-safe operation via message passing
Installation
Add chrondb from crates.io:
cargo add chrondbOr add it directly to your Cargo.toml:
Native shared library
The crate requires the libchrondb native library at runtime. Download it from the latest GitHub release:
macOS (Apple Silicon):
Linux (x86_64):
Configure the runtime library path
The shared library must be discoverable at runtime:
Linux:
macOS:
Library path (advanced)
To override the library location at build time, set CHRONDB_LIB_DIR:
Quick Start
Legacy API (deprecated):
ChronDB::open("/tmp/data", "/tmp/index")still works but is deprecated. Useopen_pathinstead.
API Reference
ChronDB::open_path(db_path) -> Result<ChronDB>
Opens a database connection using a single directory path. Data and index are stored in subdirectories automatically.
db_path
&str
Path for the database (data and index stored inside)
Returns: Result<ChronDB>
Errors: IsolateCreationFailed, OpenFailed(reason)
ChronDB::open(data_path, index_path) -> Result<ChronDB> (deprecated)
Deprecated. Use
open_pathinstead. This method still works but will be removed in a future release.
Opens a database connection with separate data and index paths.
data_path
&str
Path for the Git repository (data storage)
index_path
&str
Path for the Lucene index
Returns: Result<ChronDB>
Errors: IsolateCreationFailed, OpenFailed(reason)
ChronDB::builder(data_path, index_path) -> ChronDBBuilder
Creates a builder for opening a database with custom options like idle timeout.
data_path
&str
Path for the Git repository (data storage)
index_path
&str
Path for the Lucene index
Returns: ChronDBBuilder
ChronDBBuilder::idle_timeout(duration) -> Self
Sets the idle timeout for the GraalVM isolate. When no operations happen for the specified duration, the isolate is automatically closed to free CPU and memory. The next operation transparently reopens it.
duration
Duration
Max idle time before suspending the isolate
ChronDBBuilder::open() -> Result<ChronDB>
Opens the database with the configured options.
Errors: IsolateCreationFailed, OpenFailed(reason)
Example
put(&self, id, doc, branch) -> Result<serde_json::Value>
Saves a document.
id
&str
Document ID (e.g., "user:1")
doc
&serde_json::Value
Document data as JSON value
branch
Option<&str>
Branch name (None for default)
Returns: The saved document as serde_json::Value.
Errors: OperationFailed(reason)
get(&self, id, branch) -> Result<serde_json::Value>
Retrieves a document by ID.
id
&str
Document ID
branch
Option<&str>
Branch name
Returns: The document as serde_json::Value.
Errors: NotFound, OperationFailed(reason)
delete(&self, id, branch) -> Result<()>
Deletes a document by ID.
id
&str
Document ID
branch
Option<&str>
Branch name
Returns: Ok(()) on success.
Errors: NotFound, OperationFailed(reason)
list_by_prefix(&self, prefix, branch) -> Result<serde_json::Value>
Lists documents whose IDs start with the given prefix.
prefix
&str
ID prefix to match
branch
Option<&str>
Branch name
Returns: JSON array of matching documents (empty array if none).
list_by_table(&self, table, branch) -> Result<serde_json::Value>
Lists all documents in a table.
table
&str
Table name
branch
Option<&str>
Branch name
Returns: JSON array of matching documents (empty array if none).
history(&self, id, branch) -> Result<serde_json::Value>
Returns the change history of a document.
id
&str
Document ID
branch
Option<&str>
Branch name
Returns: JSON array of history entries (empty array if none).
query(&self, query, branch) -> Result<serde_json::Value>
Executes a query against the Lucene index.
query
&serde_json::Value
Query in Lucene AST format
branch
Option<&str>
Branch name
Returns: Results object with results, total, limit, offset.
Errors: OperationFailed(reason)
execute_sql(&self, sql, branch) -> Result<serde_json::Value>
Executes a SQL query directly against the database without needing a running server.
sql
&str
SQL query string
branch
Option<&str>
Branch name (None for default)
Returns: Result object with type, columns, rows, count.
Errors: OperationFailed(reason)
setup_remote(&self, remote_url) -> Result<serde_json::Value>
Configures a remote Git repository URL for syncing.
Returns: {"type":"ok","remote_url":"..."} on success.
Errors: OperationFailed(reason)
push(&self) -> Result<serde_json::Value>
Pushes local changes to the configured remote repository.
Returns: {"type":"ok","status":"pushed"} on success, {"type":"ok","status":"skipped"} if no remote is configured.
Errors: OperationFailed(reason)
pull(&self) -> Result<serde_json::Value>
Pulls changes from the configured remote repository. Fetches and fast-forwards the local branch.
Returns: {"type":"ok","status":"pulled|current|skipped|conflict"}.
Errors: OperationFailed(reason)
fetch(&self) -> Result<serde_json::Value>
Fetches changes from the configured remote without merging.
Returns: {"type":"ok","status":"fetched|skipped"}.
Errors: OperationFailed(reason)
remote_status(&self) -> Result<serde_json::Value>
Returns whether a remote repository is configured.
Returns: {"type":"ok","configured":true|false}.
Errors: OperationFailed(reason)
last_error(&self) -> Option<String>
Returns the last error message from the native library, if any.
Drop
The ChronDB struct implements Drop. When it goes out of scope, the database connection is closed and the GraalVM isolate is torn down automatically.
Document ID Convention
Documents use the format table:id:
Internally, user:123 is stored as user/user_COLON_123.json in the Git repository.
Use list_by_table("user") to retrieve all documents in the user table.
Error Handling
ChronDBError Enum
All variants implement Display and std::error::Error.
The crate also provides a type alias:
Conversion
serde_json::Error is automatically converted to ChronDBError::JsonError via From.
Example
Examples
Full CRUD
Query
History (Time Travel)
SQL Queries
Execute SQL queries directly without needing a running server:
Remote Sync
Using with Drop (automatic cleanup)
Idle Timeout (long-running services)
ChronDB loads a GraalVM native-image shared library whose internal threads consume CPU even when no operations are in flight. For long-running services with sporadic database access, use idle_timeout to automatically suspend the isolate when idle:
When to use:
Long-running daemons that write to ChronDB intermittently (e.g., audit logging, MCP servers)
Services where memory/CPU usage matters during idle periods
When NOT to use:
Short-lived CLI tools (just use
ChronDB::open)High-throughput services with constant database access (the isolate would never go idle)
Export & Backup
Export to Directory
Backup & Restore
Building from Source
build.rs Behavior
The build script (build.rs):
Reads
CHRONDB_LIB_DIR(defaults to../../target)Configures
rustc-link-searchandrustc-link-lib=dylib=chrondbIf
libchrondb.handgraal_isolate.hexist in that directory, generates FFI bindings viabindgenOtherwise, uses stub bindings (
src/ffi_stub.rs) to allow compilation without the native library
Last updated
Was this helpful?