Battle-tested, schema-first data models for Internet Computer canisters. Built for Dragginz, now open to everyone.
IcyDB is a Rust framework for building strongly-typed, queryable data models inside Internet Computer canisters.
It provides:
- declarative entity definitions,
- typed query intent with explicit semantics,
- deterministic planning and execution,
- and stable-memoryβbacked storage with predictable behavior.
IcyDB is designed for single-message atomicity, explicit correctness guarantees, and mechanical enforcement of architectural boundaries.
- Entity macros β define schema-first entities declaratively.
- Typed query intent β build queries as
Query<E>with explicit semantics. - Deterministic planning β validated, executor-safe plans only.
- Stable storage β data is persisted in stable memory (not heap), backed by CanIC B-trees.
- Path dispatch β
icydb_buildgenerates internal routing helpers. - Observability endpoints β
icydb_snapshot,icydb_metrics,icydb_metrics_reset. - IC integration β ergonomic
icydb::start!andicydb::build!macros. - Testability β fixtures, predicate validation, index testing utilities.
- Rust 1.93 (edition 2024)
- Install with:
rustup toolchain install 1.93
Use a pinned git tag for reproducible builds:
[dependencies]
icydb = { git = "https://github.com/dragginzgame/icydb.git", tag = "v0.0.1" }use icydb::prelude::*;
#[entity(
sk(field = "id"),
fields(
field(ident = "id", value(item(is = "types::Ulid"))),
field(ident = "name", value(item(is = "text::Name"))),
field(ident = "description", value(item(is = "text::Description"))),
),
)]
pub struct User {}Queries are built as typed intent, explicitly planned, and then executed.
For session-bound fluent queries, use db!().load::<User>() (returns SessionLoadQuery)
or db!().delete::<User>() (returns SessionDeleteQuery).
use icydb::prelude::*;
#[query]
pub fn users_named_ann() -> Result<Vec<UserView>, icydb::Error> {
let query = Query::<User>::new(ReadConsistency::MissingOk)
.filter(eq("name", "ann"))
.order_by("name")
.offset(100)
.limit(50);
let plan = query.plan()?;
let rows = db!().load_executor::<User>().execute(plan)?;
Ok(rows.views())
}Key properties:
- Entity type is fixed at construction (
Query<User>). - Missing-row behavior is explicit (
ReadConsistency). - Executors only accept validated, executable plans.
- Query semantics are API-surface dependent:
FieldRefandFilterExpruse different coercion defaults for ordering. Seedocs/QUERY_BUILDER.mdfor the locked contract.
icydb/β meta crate re-exporting the public API.crates/icydb-coreβ runtime (entities, traits, query engine, stores).crates/icydb-schema-deriveβ proc-macros for schema, traits, and views.crates/icydb-schemaβ schema AST, builder, and validation.crates/icydb-buildβ build-time codegen for actors, queries, metrics.crates/test,crates/test_designβ integration and design tests.assets/,scripts/,Makefileβ docs, helpers, workspace tasks.
The following endpoints are generated automatically:
icydb_snapshot()β liveStorageReporticydb_metrics()β metrics since a given timestampicydb_metrics_reset()β clears metrics state
Example usage:
dfx canister call <canister> icydb_snapshot
dfx canister call <canister> icydb_metrics
dfx canister call <canister> icydb_metrics_resetWorkspace commands (see Makefile):
make check # type-check workspace
make clippy # lint (warnings denied)
make test # unit + integration tests
make fmt # format workspace
make build # release buildPre-commit hooks run:
cargo fmt -- --checkcargo sort --checkcargo sort-derives --check
- Prefer typed errors (
thiserror) over panics in library code. - Keep functions small and single-purpose.
- Use explicit semantics over implicit defaults.
- Co-locate unit tests; integration tests live under
crates/test*. - No backward-compatibility guarantee yet β breaking changes are documented.
- Git tags are treated as immutable by project policy.
- Production users should always pin to a specific tag.
- Floating branches are not recommended for production.
Verify available tags:
git ls-remote --tags https://github.com/dragginzgame/icydb.git- Expanding documentation and runnable examples.
- Increasing test coverage across query and index paths.
- Tracking memory usage and store statistics in production.
- Reducing WASM size produced by
icydb_build.
Licensed under either of:
- Apache License, Version 2.0 (
LICENSE-APACHE) - MIT License (
LICENSE-MIT)
at your option.
