A collection of reusable Nix flakes for configuring reproducible development environments across oolio-group projects.
Each stack (Go, Node/Bun, Python, Protobuf, …) is its own flake with an
independently pinned nixpkgs. A project composes the stacks it needs and
upgrades them one at a time — e.g. nix flake update go bumps Go's nixpkgs
without touching the version of bun, protobuf, or anything else.
All stacks build against the oolio-group/nixpkgs
fork (nixpkgs-unstable) and support x86_64/aarch64 on Linux and macOS.
flake.nix top-level — bootstrap template + this repo's dev shell
stacks/
common/ jq, git, cacert, direnv (include exactly ONCE)
go/ go_1_26, gotools, air
node/ nodejs_24, bun
python/ python3, uv, ruff
protobuf/ protobuf, protoc-gen-*, buf
templates/
dev/ starter consumer flake.nix + .envrc
Each stacks/<name>/ contains:
packages.nix— the language/tool bundle, apkgs -> [ derivation ]functionflake.nix— pins its ownnixpkgsand exposes:devPackages.<system>— the composable bundle (use this when mixing stacks)devShells.<system>.default— a standalone shell (nix develop ...?dir=stacks/go)
nix flake init -t github:oolio-group/flakesThis drops a flake.nix (+ .envrc) wired to compose common + go + node.
Edit the inputs and buildInputs to add/remove stacks. Enter with
nix develop, or direnv allow if you use direnv.
{
inputs = {
nixpkgs.url = "github:oolio-group/nixpkgs/nixpkgs-unstable";
common.url = "github:oolio-group/flakes?dir=stacks/common";
go.url = "github:oolio-group/flakes?dir=stacks/go";
node.url = "github:oolio-group/flakes?dir=stacks/node";
protobuf.url = "github:oolio-group/flakes?dir=stacks/protobuf";
};
outputs = { self, nixpkgs, common, go, node, protobuf, ... }:
let
forAllSystems = nixpkgs.lib.genAttrs
[ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
in {
devShells = forAllSystems (system: {
default = (import nixpkgs { inherit system; }).mkShell {
buildInputs =
common.devPackages.${system} # include once
++ go.devPackages.${system}
++ node.devPackages.${system}
++ protobuf.devPackages.${system};
};
});
};
}The tools in each stack come from that stack's pinned nixpkgs, not from the top-level
nixpkgsinput. The top-levelnixpkgsis only used formkShelland any ad-hoc packages you add yourself.
| Goal | Command (run in the consuming repo) |
|---|---|
| Upgrade only Go's nixpkgs | nix flake update go |
| Upgrade only the JS stack | nix flake update node |
| Upgrade everything | nix flake update |
To change a version within a stack (e.g. Go 1.26 → 1.27), edit the attribute
in stacks/<name>/packages.nix (go_1_26 → go_1_27). If the current pin
doesn't carry that version yet, also nix flake update <stack>.
Include
commonexactly once. The language stacks deliberately omit generic tools (git/jq/…) so a merged shell doesn't end up with several copies pulled from different nixpkgs revisions.
- Create
stacks/<name>/packages.nix— apkgs -> [ derivation ]bundle. - Create
stacks/<name>/flake.nix(copy an existing stack; only thedescription, thepackages.niximport, and theshellHookdiffer). git addthe files and runnix flake lock ./stacks/<name>.