{"id":32197023,"url":"https://github.com/karpfediem/rx.nix","last_synced_at":"2026-07-11T18:32:19.077Z","repository":{"id":318951295,"uuid":"1075013731","full_name":"karpfediem/rx.nix","owner":"karpfediem","description":"Reactive Nix: Enabling Functional Reactive Configuration with mgmt","archived":false,"fork":false,"pushed_at":"2026-01-30T00:13:50.000Z","size":173,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-30T12:22:01.858Z","etag":null,"topics":["functional-reactive-programming","mgmtconfig","nix","nixos"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/karpfediem.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-12T22:28:55.000Z","updated_at":"2026-01-30T11:06:42.000Z","dependencies_parsed_at":"2025-10-17T11:22:50.887Z","dependency_job_id":"70234058-f8e0-4d17-a3a5-1a1204cd86b1","html_url":"https://github.com/karpfediem/rx.nix","commit_stats":null,"previous_names":["karpfediem/rx.nix"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/karpfediem/rx.nix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karpfediem%2Frx.nix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karpfediem%2Frx.nix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karpfediem%2Frx.nix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karpfediem%2Frx.nix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karpfediem","download_url":"https://codeload.github.com/karpfediem/rx.nix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karpfediem%2Frx.nix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35372639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-reactive-programming","mgmtconfig","nix","nixos"],"created_at":"2025-10-22T02:48:42.542Z","updated_at":"2026-07-11T18:32:19.065Z","avatar_url":"https://github.com/karpfediem.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `rx.nix` - Reactive Nix\n\n\u003e **Enabling Functional Reactive Configuration with mgmt**\n\n\n## Motivation\n\nNix lets us define entire systems as pure functions - deterministic, reproducible, and immutable.\nEach build yields a perfectly reproducible system generation, a snapshot of declarative intent made concrete.\n\nHowever, once evaluated, these functions produce *fixed values*: the system stops evolving until we rebuild it.\nThe world changes - secrets rotate, services start, fail and stop, peers reappear on the network - but the configuration does not react.\n\n### The missing dimension: time\n\nIn Nix, a derivation represents a pure mathematical function:\n\n```go\nsystem = f(configuration)\n```\n\nThis guarantees purity and reproducibility - but it also locks time out of the model.\nA system generation can be correct now and outdated a moment later, and the only way to react is to rebuild.\n\n**Functional Reactive Programming (FRP)** extends this idea:\n\n```go\nsystem(t) = f(configuration, environment(t))\n```\n\nHere, configurations remain pure, yet they depend on **signals** - values that evolve continuously as their environment changes.\nFRP enables declarative systems that stay correct over time.\n\n---\n\n## The Idea\n\n**`rx.nix`** (Reactive Nix) explores how Nix's functional evaluation model can integrate with **mgmt's** FRP runtime - a configuration management engine that reacts to change in real time.\n\nWhile Nix provides the *specification* of a system, `mgmt` provides the *motion*:\na continuous reconciliation loop that enforces the declared state automatically.\n\nThe combination is simple but potentially very powerful:\n\n* Nix defines **what** the system should look like.\n* mgmt ensures it **stays that way** - continuously, safely, and declaratively.\n\nThis fusion opens the door to systems that are not only reproducible at build time but **reactively self-correcting** at runtime.\n\n---\n\n## Current Struggles\n\n**1. Static evaluation**\nNix systems are static between rebuilds. Drift or external changes require explicit intervention.\n\n**2. Secret management**\nSecrets in Nix are typically static, baked into store paths or decrypted at build time.\nIntegrating a reactive engine allows external secret stores (Vault, 1Password, etc.) to feed live data into configuration safely.\n\n**3. Declarative dynamic Configuration**\nToday, \"dynamic\" configuration in Nix often means templating or scripting (custom logic running on activation, or as a background service).\nFRP makes *pure dynamism* possible - logic that depends on live system signals while preserving functional semantics.\n\n**4. State awareness**\nTraditional Nix evaluation is blind to runtime state. mgmt introduces live feedback loops that can reapply, heal, or reconfigure in response to drift or dependency changes.\n\n---\n\n## How It Works\n\n`rx.nix` is a **nixos module** that lets users define reactive configuration inside regular nixosConfigurations.\nIt also provides additional outputs via a flake module.\n\n### Example\n\n```nix\n{\n  imports = [ rx.flakeModules.default ];\n\n  nixosConfigurations.demo = lib.nixosSystem {\n    system = \"x86_64-linux\";\n    modules = [\n      rx.nixosModules.default\n      ({ ... }: {\n        rx.enable = true; # enable module\n        rx.mgmt.enable = true; # enable mgmt systemd service\n\n        rx.mcl.imports = [ \"datetime\" \"golang\" ]; # set up required imports (either here or in MCL code)\n        rx.mcl.vars.d = \"datetime.now()\"; # reactive variables\n\n        # Write raw MCL code\n        # Define your own reactive files (try to `watch -n 0.1 cat /tmp/now`)\n        rx.mcl.raw = [\n          ''\n            file \"/tmp/now\" {\n              state =\u003e $const.res.file.state.exists,\n              content =\u003e golang.template(\"Hello! It is now: {{ datetime_print . }}\\n\", $d),\n            }\n          ''\n        ];\n      })\n    ];\n  };\n}\n```\nThe nixosModule will generate a bundled up MCL module and set it as your current profile on system activation.\nThe included systemd service will ensure your configuration is applied continuously during runtime of your system.\n\nAdditionally, the flake module provides these new outputs:\n\n| Output                        | Description                             |\n| ----------------------------- | --------------------------------------- |\n| `rxSystems.\u003csystem\u003e.\u003chost\u003e`   | Built mgmt generations per host         |\n| `rxIrForHost.\u003chost\u003e`          | Per-host intermediate representation    |\n| `rxGenForHost.\u003chost\u003e`         | Materialized mgmt configuration payload |\n| `apps.rxSwitchForHost.\u003chost\u003e` | CLI app to switch the active generation |\n\n---\n\n## Example IR\n\n```json\n{\n  \"demo\": {\n    \"files\": [\n      {\n        \"path\": \"/etc/hosts\",\n        \"owner\": \"root\",\n        \"mode\": \"0644\",\n        \"__source\": \"/nix/store/...-hosts\"\n      },\n      {\n        \"path\": \"/tmp/hello\",\n        \"owner\": \"root\",\n        \"mode\": \"0644\",\n        \"__content\": \"Hello from rx module\\n\"\n      }\n    ]\n  }\n}\n```\n\nThis **Intermediate Representation (IR)** serves as the bridge between Nix's static world and mgmt's reactive runtime.\n\n---\n\n## Vision \u0026 Motivation\n\n**Reactive Nix** isn't about replacing NixOS or mgmt.\nIt's about exploring what happens when we bring *time* into functional configuration.\n\nThe questions driving this project are:\n\n* Can we cleanly combine purity and reactivity without giving up determinism?\n* Which new possibilities emerge when configuration is truly *alive*?\n\n---\n\n## Rough Roadmap\n\n| Phase | Feature / Exploration                                  | Status        |\n|-------|--------------------------------------------------------|---------------|\n| I     | File resources (`rx.files`, `rx.include.files`)        | ✅ Implemented |\n| II    | Per-host evaluation (`rxGenForHost`, `rxIrForHost`)    | ✅ Implemented |\n| III   | Full MCL resource mapping (via codegen)                | ✅ Implemented |\n| IV    | External secrets integration (Vault, 1Password, SOPS)  | 🔄 Planned    |\n| V     | Live mgmt evaluation backend (MCL codegen refactor)    | 🔄 Planned    |\n| VI    | Full dynamic dependencies (signals between hosts)      | 🚧 Research   |\n| VII   | Cross-platform expansion (macOS via nix-darwin)        | 🚧 Research   |\n| VIII  | Conceptual FRP primitives in Nix (mkSignal, mkDynamic) | 🚧 Research   |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarpfediem%2Frx.nix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarpfediem%2Frx.nix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarpfediem%2Frx.nix/lists"}