Overview

A Vue + JSONForms widget bundle that renders a NixOS-module-derived JSON Schema in a deploy-vs-baseline diff workflow, with per-field change highlighting.

The pipeline

The name is a little misleading, so it is worth being blunt about what this repository does and does not do: it evaluates no Nix. There is no NixOS module here, nothing imports nixpkgs.lib, and nothing reads a .nix file at runtime. It is a JavaScript bundle that consumes a JSON Schema.

Turning a NixOS module into a working web form takes two libraries, and neither does it alone:

NixOS module
    |
    |  module-schema (optionsToSchema)      <- evaluates the module system
    v
JSON Schema
    |
    |  nix-module-form (this repo)          <- renders it, no Nix involved
    v
edited JSON value
    |
    |  the embedder                         <- validates and writes it back
    v
Nix configuration

The upstream half is fediversity/module-schema (docs), which converts lib.types option declarations into JSON Schema. This half renders that schema and hands back an edited value. The two are deliberately separable: the generator is useful without a form, and the form is useful against any Nix module-shaped JSON Schema.

The downstream half -- deciding what "deploy" means, where the value is stored, who is allowed to press the button -- belongs to whoever embeds the widget. See Usage.

What this adds over stock JSONForms

Pointing vanilla JSONForms at a generated schema gets you a form, but not one for which NixOS option types map cleanly onto the shapes a generic renderer expects. This bundle adds:

  • Nix module-shaped renderers. A nullOr option becomes a "Configure / use the default" toggle rather than a bare oneOf variant picker; an attrTag discriminated union becomes a single tag <select> with only the chosen branch's fields below it (retaining shared fields across a switch); an attrsOf map's new-key input accepts the Nix attrName key type, which a default AJV rejects. The full contract is in schema shapes.
  • A deploy-vs-baseline diff. Every field is highlighted against the last-deployed configuration -- added, changed, or reverted -- rather than against whatever the form happened to load. On top of that sits a schema-change layer: which options were added, removed, renamed, or retyped since that deployment, with the old value shown read-only beside the new field.
  • NixOS-aware validation. Schema defaults are deliberately not filled into the value, so an absent key keeps meaning "follow the Nix default" instead of freezing today's default into the stored config.

Who uses it

The fediversity panel is the real-world consumer: it pins this repo, supplies its own entry adapter, and wires the form to its deployment API. This repository was extracted from that monorepo so the widget can version and ship on its own.

Where to go next

  • Usage -- pinning, building, mounting, the API reference, the schema shapes, and the gotchas.
  • Demo -- two self-contained pages running the whole pipeline.
  • Comparison -- how this relates to clan, nixos-conf-editor, thymis, and other Nix-configuration UIs.
  • Flake attributes -- this repo's own outputs.