Why We're Moving on from Nix
How Railway Used Nix / Nixpacks
- Nix was mostly hidden from end users: you could push code without a Dockerfile and Railway built images via Nixpacks behind the scenes.
- Commenters ask why Railway needed to constrain user versions at all if the whole point of Nix is “you get exactly what you asked for.”
Versioning, Caches, and “Commit-Based” Model
- The blog’s claim that only latest major versions were usable and older ones weren’t cached is disputed: multiple comments say the public Nix cache keeps huge history and old binaries.
- Clarification: Nixpkgs usually keeps a single version per package per channel; if you want older versions with newer dependencies, you either:
- Pin older nixpkgs commits or
- Use overlays / custom derivations or ecosystem-specific tooling.
- Some see Railway’s complaint as unfamiliarity or NIH; others note that mapping “Ruby 3.1 + GCC 12 + …” onto the nixpkgs model is genuinely awkward for a platform that lets users pick arbitrary language versions.
Image Size and Docker Layering
- The article’s claim that Nix caused one giant
/nix/storelayer and huge images is heavily questioned. - Several people point out that Nix can:
- Automatically trim runtime dependencies (only referenced store paths).
- Build layered images via
dockerTools.buildLayeredImage/streamLayeredImageor nix2container, with examples of small images and shared layers.
- Others acknowledge Nix Docker images often do end up bloated in practice, especially when naively combining Nix and Docker.
Nix UX, Learning Curve, and Nix vs Nixpkgs
- Repeated theme: Nix is powerful but hard to learn, poorly documented in places, with opaque errors.
- Defenders stress: Nix (the build system) is distinct from Nixpkgs (the big package set); production users are expected to add overlays and custom package sets.
- Critics argue that if “basic” needs constantly require deep Nix knowledge and custom code, the UX is failing, especially for a developer platform.
Philosophy: Curated Sets vs “Bespoke Version Soup”
- One side: language-level version ranges and per-project mixes (“version soup”) are fragile and unsustainable; Nixpkgs’ atomic, curated package sets plus backported security fixes are a better model.
- The other side: that model makes it painful to upgrade or pin a single tool without dragging an entire package universe; some recount having to roll back whole system updates due to regressions.
Perception of Railway’s Move and Motives
- Several commenters see the blog as marketing for a new product (Railpack) rather than a deep technical postmortem.
- The simultaneous switch away from Nix and from Rust to Go is read by some as a “full rewrite” driven more by team preferences, hiring, or VC/traction positioning than by insurmountable Nix limitations.
- Others accept that, even if Nix could technically solve these issues, Railway may reasonably prefer a simpler, more conventional stack (Buildkit, OCI tools, language managers) for their target audience.
Alternatives and Broader Tradeoffs
- Alternatives mentioned: devenv, mise, asdf-style tools, Pixi/Conda, Bazel, Guix, traditional containers/VMs.
- General consensus: there are no silver bullets; Nix trades compute cost and complexity for determinism, while Railway’s new approach trades some guarantees for familiarity and perceived ease.