Accepted
Initially attempted to have everything in one qntx crate with feature flags. This was naive - as the codebase grew and more crates were added (qntx-core, qntx-sqlite, qntx-wasm), it became clear that bundling types with gRPC infrastructure creates unnecessary dependencies.
The key realization: A WASM module that just needs type definitions shouldn't pull in 50+ gRPC-related dependencies.
Separate proto types from gRPC infrastructure using two distinct crates:
qntx-proto: Pure types using prostqntx-grpc: gRPC services using tonic (depends on qntx-proto)Uses prost for minimal proto → Rust type generation:
[dependencies]
prost = "0.13"
prost-types = "0.13"
serde = { workspace = true }
[build-dependencies]
prost-build = "0.13"
protoc-bin-vendored = "3.1" # No protoc installation required
Total dependencies: ~5
Build-time generation with protoc-bin-vendored:
Build.rs configuration:
let mut config = prost_build::Config::new();
config.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]");
config.compile_protos(&protos, &[&proto_dir])?;
Uses tonic for full gRPC service generation:
[dependencies]
qntx-proto = { path = "../qntx-proto", optional = true }
tonic = { workspace = true, optional = true }
tokio = { workspace = true, optional = true }
# ... 50+ transitive dependencies
Simple rule: Use qntx-proto unless you specifically need gRPC services.
// WASM module - just needs types
[dependencies]
qntx-proto = { path = "../qntx-proto" }
// gRPC plugin - needs services
[dependencies]
qntx-grpc = { path = "../qntx-grpc", features = ["plugin"] }
Gradual replacement:
qntx-sqlite/src/proto_convert.rs)Having everything in one crate "probably isn't the way to go" - this became obvious as more crates were added. The initial approach was underdeveloped. Working on qntx-sqlite, qntx-wasm, and other crates revealed that different consumers have vastly different needs.
The dependency explosion from gRPC was the key driver. When you just need to know what an Attestation looks like, you shouldn't need to compile tokio, hyper, and tower.