Skip to content

Dependencies

Draft

This doc is the single owner of Capsule’s canonical implementation-dependency pins: for each domain concern, the one library that implements it, where the pin applies, and the bounded exceptions. Introducing a dependency for a domain not listed here requires adding a row here first; changing a pin is a one-doc edit plus a migration slice in the repo-root SLICES.md — never an in-place drift.

What this doc deliberately does not own, per the SSoT rule:

Mechanically, every Rust version is pinned once in the root Cargo.toml [workspace.dependencies]; member crates consume it with workspace = true and never declare their own version. Toolchain versions (Rust nightly, bun, tuist, …) are pinned by mise per CONTRIBUTING.md.

DomainCanonical choiceScopeExceptions
DatetimejiffAll domain logic — parsing, formatting, arithmetic. Signed and wire formats carry RFC 3339 strings or integer epochs, never a datetime library type, so the pin never touches serialized bytes.chrono remains only as the sea-orm column type in the entity crates (capsule-api/entity, capsule-cli/entity), converted to jiff at the entity boundary, and in the frozen capsule-api-library (async-graphql chrono scalars), which retires with slice S-G1.
Error handlingthiserror in libraries; eyre + color-eyre in binariesLibraries define typed error enums; binaries (CLI, server main, xtask) wrap them in reports.anyhow is not used.
Loggingtracing (facade) + tracing-subscriber (binaries)All crates; structured fields and hot-path spans per the traceability rule in AGENTS.md. The log facade is forbidden in new code.Remaining log:: call sites in capsule-core / capsule-core-ffi migrate in slice S-F6.
TLS implementationrustlsWherever Capsule code holds a TLS stack: the SDK’s HTTP client, LAN-peering mutual TLS, server egress, sea-orm’s runtime-tokio-rustls. Never native-tls/openssl.openssl appears only as a transitive dependency of webauthn-rs attestation-certificate verification — it is never a TLS stack.
IdentifiersuuidUUIDv7 for every newly introduced identifierTime-ordered v7 is the default (index locality); the assignment of existing ids is owned by Metadata — Identifiers.UUIDv4 where an id must not leak creation time (e.g. device_id). Capability-bearing opaque ids (share links, drops) are not UUIDs at all — they carry their own ≥128-bit entropy per their owner docs.
Async runtimetokioAll async code.
HTTP serversalvocapsule-api REST surfaces.
gRPCtonic + prostThe capsule.sync.v1 feed per API Surfaces.
HTTP clientreqwest (default-features = false, rustls-tls)capsule-sdk — the sanctioned network path.
ORMsea-orm (sqlx-postgres on the server, sqlx-sqlite in the CLI)The rebuildable index databases only — sidecars stay canonical per Principles.
Embedded SQLiterusqlite (bundled)capsule-core’s library.sqlite.
CBORciborium (+ serde_bytes, half)All CBOR; the canonical-encoding rules are owned by Metadata — Canonical CBOR Encoding.
Serializationserde + serde_jsonDerives and JSON surfaces.
CLIclap (derive)capsule-cli, xtask argument parsing where non-trivial.
Test runnercargo-nextest; testcontainers (+ podman) for real backing servicesThe Unit/Smoke tiers per Principles — Validation Tiers.
FFI bindingsuniffiOne workspace version — consolidation is slice S-F1.
DomainCanonical choiceNotes
FrameworkReact 19 + rsbuild
Routing / dataTanStack Router / TanStack Query
StylingTailwind v4, class-based dark mode (@custom-variant dark + ThemeProvider)
Validationzod
Datetimenone — native Intl / DateA date library is added only by adding a row here.
i18n runtimeFormatJS over the generated catalogsContract owned by Internationalization.
Lint/formatBiome
Runtime / package managerbun

Test frameworks and performance tooling are owned by Clients — Test and Performance Tooling. Bindings come from the single-version uniffi strategy (slice S-F1). Project generation and formatting (Tuist, SwiftLint, SwiftFormat) are mise-pinned toolchain, not library pins.

Bindings likewise ride the uniffi strategy (S-F1); JNA loads the produced library. JUnit 5 is the current test harness; the canonical pin is recorded in Clients — Test and Performance Tooling when the Android harness stabilizes.

The pins are enforced structurally, not by convention: cargo tree -i chrono -e no-dev must resolve to the entity crates, the frozen library crate, and sea-orm internals only; rg 'log::' outside the S-F6 scope, and any openssl/native-tls edge outside webauthn-rs, are review-blocking. The per-platform mise run check-* gates run the pinned toolchains.