Feature Specification: Package, Demo and Documentation
Created: 2026-09-22
Status: Implemented
Input: Reconstructed from the code at d225ebe (default.nix, flake.nix, shell.nix, package.nix, vite.config.ts, patches/, test.nix, dom-test.nix, nix/demo.nix, nix/docs.nix, nix/screenshots.nix, nix/take-screenshots.py, demo/, docs/, .forgejo/workflows/), the pull requests of fediversity/nix-module-form about the documentation, the demo, the screenshots and the flake, the history of the extraction from the fediversity monorepo, and the Claude Code logs of the maintainers.
User Scenarios & Testing (mandatory)
User Story 1 - Build the bundle for a host page (Priority: P1)
An embedder builds the widget with Nix and serves the JavaScript and CSS files on its page. When the embedder needs glue code for its page (for example to read the value from a hidden input), it gives one TypeScript file as entry. The build puts that file next to the library source and bundles it as the entry point.
Why this priority: the widget is useful only when an embedder can build it and add its own glue without a fork.
Independent Test: build packages.default, and build the demo, which uses its own entry.
Acceptance Scenarios:
- Given no
entry, When the package builds, Then the output containsnix-module-form.jsandnix-module-form.cssbuilt fromsrc/index.ts. - Given an
entryfile that imports./index, When the package builds with it, Then the bundle starts from that file and contains the library. - Given the pinned npm lock file, When the package builds twice, Then the outputs are the same.
User Story 2 - Try the widget without a host (Priority: P1)
A developer runs nix run .#demo and opens the printed address. Two pages show the widget with the demo module: one with a value and a baseline, one with two versions of the module and a rename.
Why this priority: a developer must see the widget before they decide to embed it, and the maintainers need a page to test changes.
Independent Test: run nix run .#demo and open both pages.
Acceptance Scenarios:
- Given the demo is built, When a developer runs
nix run .#demo, Then an HTTP server serves the pages, because ES modules do not load fromfile://. - Given
demo/module.nix, When the demo builds, Then its schemas come from module-schema at build time, not from a stored copy.
User Story 3 - Read the documentation (Priority: P2)
A developer reads the documentation site: an overview, the usage with the API reference and the supported schema shapes, the demo with images, and a comparison with similar tools.
Why this priority: embedders need the API and the schema contract, and they need to know when a different tool fits better.
Independent Test: build packages.docs and open the result.
Acceptance Scenarios:
- Given the sources under
docs/, Whennix build .#docsruns, Then the result is the complete site, with the images from the demo. - Given a change to the demo, When the
screenshotspackage builds, Then a headless browser captures new images in the light and the dark theme, after the page issettledand with transitions off. - Given a merge to
main, When the publish workflow runs, Then the site is published.
User Story 4 - Develop and test (Priority: P2)
A contributor enters the development shell, changes the source and runs the checks.
Why this priority: fast, reproducible checks keep changes safe.
Independent Test: run nix develop (or nix-shell) and nix flake check.
Acceptance Scenarios:
- Given the development shell, When a contributor enters it, Then the Node toolchain of the package,
oxfmt,npinsandspec-kitare available. - Given a change, When CI runs, Then the formatter check, the unit tests, the DOM tests, the demo build, the documentation build and the image capture run as separate checks.
Edge Cases
- A flake user and a user of
import ./. { }get the same packages. The flake adds only the system layer. - A bug or a performance defect in an upstream package needs a fix before upstream has one: the build applies a patch to the vendored package after the npm dependencies are installed. The package and the DOM tests apply the same patches (
patches/vue-vuetify-additional-properties-ajv.nixandpatches/jsonforms-vue-stable-control.nix). - The browser for the images is heavy: only the
screenshotscheck needs it. Other tests run in Node with a headless DOM.
Requirements (mandatory)
Functional Requirements
- FR-001:
default.nixMUST be the single entrypoint and MUST returnpackages,apps,devShells,formatter,checksandargs, for one system.flake.nixMUST only add the system layer, andshell.nixMUST read the development shell fromdefault.nix. - FR-002: All inputs MUST be pinned with npins.
- FR-003: The package MUST build with
buildNpmPackagefrom the npm lock file and MUST output one JavaScript file and one CSS file. - FR-004: The package MUST take an optional
entryfile for the glue code of an embedder. The public interface for this ispackages.default.override { entry = ...; }ofdefault.nix. The filepackage.nixis internal. - FR-005: The demo MUST make its schemas from
demo/module.nixwith module-schema at build time, andapps.demoMUST serve the pages over HTTP. - FR-006: The
docspackage MUST build the documentation site with nix-docs-lib, including the images that thescreenshotspackage captures from the demo. - FR-007:
checksMUST contain the formatter check, the unit tests, the DOM tests, the demo build, the documentation build and the image capture. - FR-008: The development shell MUST contain the Node toolchain of the package,
oxfmt,npinsandspec-kit.
Key Entities
- Bundle: the JavaScript file and the CSS file that a host page loads.
- Entry: an optional TypeScript file of an embedder that imports the library and adds glue for its page.
- Demo: two static pages built from
demo/module.nixand its own entry. - Documentation site: the pages under
docs/, built with nix-docs-lib.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001:
nix flake checkpasses onmain. - SC-002: The published site shows images of the current demo.
- SC-003: An embedder adds its glue without a change to this repository.
Assumptions
- The documentation is published to the pages of git.fediversity.eu.
- The CI runners of fediversity run the checks. The checks do not depend on the runners.
Known Deviations
None.