Skip to content
FormalOSGitHub

One system, any distro under it

Describe your machines once, in code. FormalSpec installs them on the distro you pick and keeps them identical.

Try it: pick a distro and watch the spec change.

Pick what the installer writesspec.star
Distro

Current software every six months, with a signed kernel that Secure Boot and anti-cheat trust.Fixed releases, Classic packages, Signed kernel

Preset
Desktop
# This machine's spec. `fspec plan` shows what a change would do, `fspec apply` makes it so.
load("//modules/desktop.star", "modules", "system")

hosts = [
    host(
        name = "g815",
        platform = "x86_64-linux",
        system = system("fedora", desktop = "gnome"),
        modules = modules("fedora", desktop = "gnome"),
        users = [user("kyan", uid = 1000, groups = ["wheel"])],
        protect = ["/home"],
    ),
]

Keep the distro you trust. Make every machine on it yours.

FormalSpec describes each machine in Starlark: packages, files, services and the distro underneath. One lockfile pins every version, so every machine on the same commit runs the same software.

The installer puts that description on a new disk. NativeDesktop apps and FormalShell make it feel like one desktop from the first login.

Browse the code on GitHub

FormalSpec

Declare your machines in code and keep them identical, on any Linux distro and on macOS.

Tested on macOS, and on Fedora 44, Arch, Debian 13 and Void.

fspec switch --distro d [--release r]

Installs another distro beside this one.

What it manages

Files and hosts

Write, link or seed a file once, or merge your keys into a file the app also writes. Hosts are plain functions, so a second laptop is one line.

load("//modules/cli.star", "cli")

def laptop(name, extra = []):
    return host(
        name = name,
        platform = "x86_64-linux",
        system = image(base = "ghcr.io/ublue-os/bazzite-nvidia:stable"),
        users = [user("kyandesutter", uid = 1000, shell = "fish")],
        modules = [cli()] + extra,
    )

hosts = [laptop("g815"), laptop("e1504g")]

Services

Describe a service once, and FormalSpec writes it for each init system.

  • systemd
  • runit
  • OpenRC
  • dinit
  • s6
  • launchd

System

Run a bootc image on Fedora Atomic, Bazzite and friends, or the distro's own package manager everywhere else.

# change the base image, then apply
system = image(base = "ghcr.io/ublue-os/bazzite-nvidia:stable")

Cleanup

Delete a line and the package goes, with its services, files and app data. Changed your mind? Roll back.

fspec rollback
fspec gc --older-than 14d

Read the FormalSpec README

The installer

Pick a distro and a preset, and boot into a machine FormalSpec manages from day one. Or point it at your spec repo and get your machines back.

15 distros, from Fedora and openSUSE to Arch, Void and AerynOS. Coming soon as a bootable image.

  FormalSpec    Language · Disk · System · Preset · Account · Review · Install
  ────────────────────────────────────────────────────────────────────────────

  Choose a system

    Fedora              fixed    systemd  signed kernel    classic
    Bazzite             fixed    systemd  signed kernel    image
  ▌ Fedora Atomic       fixed    systemd  signed kernel    image
    Aurora              fixed    systemd  signed kernel    image
    Arch Linux          rolling  systemd  unsigned kernel  classic
    CachyOS             rolling  systemd  unsigned kernel  classic

  Fedora Atomic
  Fedora as an image: updates land whole and the previous one stays in the
  boot menu.

  fixed            New versions arrive in scheduled releases you upgrade to.
  systemd          Services start with systemd, as on most distros.
  signed kernel    Boots with Secure Boot on, and anti-cheat that checks
                   kernel signatures trusts it.
  image            The system is a bootc image: updates apply whole, and the
                   previous image stays bootable.
  based on Fedora  Uses Fedora's packages, with its own changes on top.
  ↑↓ Move  Enter Continue  Esc Back  ? Keys  s Spec

Apps that feel native

Describe a window once, and each OS draws it with its own widgets: AppKit on macOS, GPUI on Linux, Windows and the web.

FormalShell, coming next

A desktop shell for Hyprland, written in Rust. One process draws the bar, launcher, panels, notifications, lock screen, greeter and screensaver, and every colour comes from your wallpaper.

Ready for everyday use on Hyprland 0.56 and newer. Coming to the installer next.

Follow FormalShell on GitHub

Smaller tools

meshtop: three hosts, then the agents view.

Kyan's

  • meshtopmacOS and Linux, MIT

    Live resource usage, connections and coding agents across all your machines, in one terminal.

  • nothingctlLinux, 22 models

    Battery, noise control and EQ for Nothing and CMF headphones and earbuds, from the Linux command line.

Contributions

  • KopuzContributor

    A Rust and Dioxus music player by the Kopuz-org community. Kyan contributes to it.