

Throw an nsenter(2) on top of that chroot(2), and you’ve got yourself a container! You can totally use Nix to create a leaf-node chroot that doesn’t emit any build artifacts, but rather is just a perfectly-set-up environment to run something in. But these chroots don’t have to have build steps.

Nix “Packages” are just chroots that define build steps, so that other chroots downstream of them can ask the upstream chroot to build itself, and then import/link build artifacts from it. In other words: Nix is a manager for defining reproducible/deterministic chroots, which bootstrap themselves by grabbing other previously-defined reproducible/deterministic chroots and doing things inside them. It’s less about packages, and more about build environments. Note that this mechanism isn’t really unique to “packages” per se. Though perhaps they’ll share a git-repo cache for separately checked-out worktrees.) (But if they don’t-if they envs they reference are even slightly different-they’ll do separate builds. When you “install” a Nix “package”, you’re really just doing the moral equivalent of a recursive git-submodule checkout - each dep tells Nix to check out explicit refs of its own deps in turn, build those deps, and then link artifacts from those deps into this Nix build env.īut unlike Node.js modules, or git submodules (which form trees of refs), Nix environments form a DAG of references so if two things in your tree share the exact same “submodule ref”, they can share/reuse the existing build env and its artifacts. a specific, locked commit (or a release tarball with an explicit SHA) of the upstream source of the package. a listing of build artifacts from those upstream build-environments that should be linked into this build environment ģ. specific, locked commits of all upstream build environments Ģ. In Nix, meanwhile, each “package” is a really a build environment, consisting of:ġ. (I think this latter part is hacked around by tools like yarn, but it’s still part of the “architecture” of the Node.js package ecosystem.) makes it impossible to “share” deps and deduplicate the work of building them, even if you explicitly create two dependent libs that both depend on the same fixed version of an upstream.
Tableplus vs postico code#
still requires all the code to be “source compatible”, as it’s all still being loaded into a single interpreter, and 2. Slightly more savvy package managers, like Rubygems, allow version constraints, but only globally there can only be one resolved version of each package (this is a fundamental limitation - loading multiple versions of the same library into a single Ruby runtime would generate namespace collisions), so Rubygems emits “constraint resolution failures” when different deps want incompatible versions of something.Īnd then there’s the Node.js approach, where everything can specify its own version constraints, and gets those specified versions installed recursively into its own nested node_modules dir.
Tableplus vs postico update#
This creates long-standing update PRs in the homebrew-core repo, as the same PR that introduces an update, is expected to also then fix all the problems that introducing that update created for the rest of the ecosystem.) If a lib updates, and breaks its dependents? Too bad, the Brew maintainers need to go update all the dependents.

(And Brew is very “naive” in this regard, as formulae can’t even specify a version constraint for their formula dependencies. Which is better than nothing, but it still means that different programs can’t be fixed to rely on different locked+resolved commits of the same symbolic-named ref of a dependent formula. Nix is more sort of a… content-addressable executable environment manager.īrew has a single shared “brew env” that it executes all its installs in the context of. Of course this is different from the isolation Docker provides, but I find that for development it is the perfect middle-ground between "everything is installed globally and conflicts with each other" and "everything is so perfectly isolated I can't get anything done". If in project B I use Node.js v14, all I have to do is declare in its `default.nix` file that it uses `nodejs-14_x` and there will be no conflicts whatsoever. Once I exit it, `nodejs-12_x` is no longer available. When I run `cd /project/root & nix-shell` I'm dropped into a shell that has `nodejs-12_x` along with the rest of my "normal" shell. The project root contains a `default.nix` file that says it needs the package `nodejs-12_x`.

A tool I use extensively when developing is a "nix shell", which is a shell that's configured with a `default.nix` file.įor example, in project A I use Node.js v12.
Tableplus vs postico install#
Nix is primarily a package management tool, yes, but it provides isolation in the sense that you don't have to globally install anything (except for Nix, of course).
