This tweet shows a common problem in Nix: “Should I use crate2nix, cargo2nix, or naersk for packaging my Rust application?”
devenv solved this for development environments differently: instead of making developers package everything with Nix, we provide tools through a simple languages.rust.enable. You get cargo, rustc, and rust-analyzer in your shell without understanding Nix packaging.
But when you’re ready to deploy, you face the same problem: which lang2nix tool should you use? Developers don’t want to compare crate2nix vs cargo2nix vs naersk vs crane—they want a tested solution that works.
devenv now provides languages.rust.import, which packages Rust applications using crate2nix. We evaluated the available tools and chose crate2nix, so you don’t have to.
We’ve done this before. In PR #1500, we replaced fenix with rust-overlay for Rust toolchains because rust-overlay was better maintained. Users didn’t need to change anything—devenv handled the transition while keeping the same languages.rust.enable = true interface.
Under the hood, process-compose now runs processes through devenv-tasks run --mode all devenv:processes:<name> instead of executing them directly. This preserves all existing process functionality while adding task capabilities.
The --mode all flag ensures that both before and after tasks are executed, maintaining the expected lifecycle behavior.
Future work on process dependencies (#2037) will also address native health check support (process-compose#371), eliminating the need for manual polling scripts.
We’ve rewritten our tracing integration to improve reporting on what devenv is doing.
More importantly, devenv is now fully asynchronous under the hood, enabling parallel execution of operations. This means faster performance in scenarios where multiple independent tasks can run simultaneously.
The new progress interface provides real-time feedback on what devenv is doing:
We’re continuing to improve visibility into Nix operations to give you even better insights into the build process.
We’ve integrated SecretSpec, a new standard for declarative secrets management that separates secret declaration from provisioning.
This allows teams to define what secrets applications need while letting each developer, CI system, and production environment provide them from their preferred secure provider.
The CLI now supports specifying single packages via the --option flag (#1988). This allows for more flexible package configuration directly from the command line:
The CI container ghcr.io/cachix/devenv/devenv:v1.8 has been reduced (uncompressed) from 1,278 MB in v1.7 to 414 MB in v1.8—that’s a reduction of over 860 MB (67% smaller!).
This makes devenv container much faster to pull and more efficient in CI/CD pipelines.
Single key management - requires distributing and managing a master key
Trust requirements - everyone with the key can decrypt all secrets
Rotation complexity - departing team members require key rotation and re-encrypting all secrets
Larger teams often adopt solutions like OpenBao (the open source fork of HashiCorp Vault), requiring significant infrastructure and operational overhead. Smaller teams face a gap between simple .env files and complex enterprise solutions.
What if instead of choosing one tool, we declared secrets uniformly and let each environment use its best provider?
While secretspec run provides secrets as environment variables, your application remains disconnected from knowing which secrets it requires. The Rust SDK bridges this gap by providing type-safe access to your declared secrets.
// For backwards compatibility, export as environment variables
secretspec.secrets.set_as_env_vars();
Ok(())
}
Add to your Cargo.toml:
[dependencies]
secretspec = "0.2.0"
secretspec_derive = "0.2.0"
The application code never specifies where to get secrets - only what it needs through the TOML file. This keeps your application logic clean and portable.
We’ve started work on supporting multiple Nix implementations in devenv. The codebase now includes a backend abstraction layer that will allow users to choose between different Nix implementations.
This architectural change paves the way for integrating Snix (our development fork). While the Snix backend isn’t functional yet, the groundwork is in place for building out this Rust-based reimplementation to the C++ Nix implementation. See PR #1950 for implementation details.
Join our Discord community to share your experiences and help shape devenv’s future.
We’re particularly interested in feedback on the standardized language tooling configuration coming in 1.8 - let us know if this approach works for your use cases!