Tomato - Visual DAG editor for NixOS configurations

Visual hierarchical graph editor that generates configuration.nix and deploys via nixos-rebuild switch.

  • Nodes are Nix fragments
  • Gateways descend into subgraphs (floors)
  • NixOS merges the composed fragments automatically
  • One-click deploy to a real NixOS machine
  • OODN registry for ambient config (hostname, timezone, stateVersion…)
  • Pre-built stacks (Grafana+Prometheus, Web Server, etc.)

Built with Elixir/Phoenix. Early stage but working end-to-end.
Looking for feedback, improvement ideas, and anyone interested in contributing templates or backends.
All discussion welcome.

GitHub:

2 Likes

Hi Alex!

The description reads nice, I am searching for a nicer config editor for a while already!

Some screenshots here and/or in the README would be nice. I barely can imagine how this might look like in practice, and at the same time, I can not just try it out, as my NixOS setup is… Not quite the norm.

Also are flakes supported or flake support planned?

1 Like

Here dev.to article with screenshot Tomato

Flakes support is not yet implemented — currently targeting classic configuration.nix — but it’s high on the roadmap. The backend is pluggable so it’s a natural next step. What’s your NixOS setup if you don’t mind sharing?

1 Like

That’s a beautiful config — exactly the kind of complexity Tomato aims to make navigable visually. Flakes support is the clear gap right now.
With flakes you’d have per-host graphs, shared module subgraphs reused across machines, home-manager as another floor.
That’s the roadmap. Mind if I use your config as a reference for the flakes backend design?

For Tomato v0.2 flake support, the Walker needs a FlakeBackend that generates:

  • flake.nix with inputs from OODNs
  • flake-parts imports from gateways
  • Per-machine configuration modules from leaf content
  • The deploy command changes from nixos-rebuild switch to nixos-rebuild switch --flake .#hostname

This is totally doable with the current architecture. The DAG model already supports it — it’s just a different finalize function.

Sure, though especially the flake parts abstraction I have spun around it, might make things a little less easy :wink: