Crystal · Linux · MIT

Turn a fresh Linux machine into your machine.

One YAML file. One preview. One run. Fluxion shows you the exact commands it would execute — then runs that same traversal with mutation switched on. What you review is what happens.

$ curl --proto '=https' --tlsv1.2 -sSfL https://worxbend.github.io/fluxion.cr/install.sh | sh
Source

The installer verifies the release's published SHA-256 before writing anything, installs to ~/.local/bin/fluxion, and leaves your shell startup files alone. Read it first if you would rather not pipe a script to a shell — that is a reasonable instinct, and the script is short.

The idea

Describe the machine. See what would happen. Then let it.

Preview and run are the same code path with one flag different, so a dry run cannot describe something other than what executes.

apiVersion: initkit.io/v1alpha1
kind: WorkstationProfile
metadata:
  name: my-laptop
spec:
  target:
    os:
      distribution: arch
  phases:
    - name: system-foundation
      steps:
        - name: core-cli-tools
          kind: pacman-packages
          spec:
            packages: [git, curl, ripgrep, zsh]
fluxion validateIs this profile sound?
fluxion dry-runWhat would it do?
fluxion applyDo it.
fluxion dry-run
Fluxion · arch-workstation · dry-run
Target: arch   Host: CachyOS (amd64)

[PHASE] system-foundation
  core-cli-tools
     git ... would run
        $ sudo pacman -S --noconfirm git
     ripgrep ... would run
        $ sudo pacman -S --noconfirm ripgrep
     zsh ... would run
        $ sudo pacman -S --noconfirm zsh
[DONE] system-foundation

[PHASE] shell
  oh-my-zsh
     ~/.oh-my-zsh ... would run
        $ download https://raw.githubusercontent.com/…/install.sh
          verify 95118b50d0…0172b61 run sh
[DONE] shell

⚠ Restart required
  Default shell changed to zsh. Log out and back in,
  then re-run fluxion.

Summary: 0 ok · 0 failed · 0 skipped · 34 would run
Trust

What it refuses to do

A bootstrapper runs privileged commands on a machine you have not finished setting up. Each of these is deliberate, and each has a reason.

no It will not run unverified bytes it fetched itself.

Every download Fluxion makes is HTTPS-only with no URL credentials, re-validated after each redirect — a redirect is an attacker-controllable hop — size-bounded while streaming rather than after, and digest-checked before use. A release asset that is not in Fluxion’s pinned digest catalog is not installed.

no It will not pretend to verify what it delegates.

Installing binaries is binstaller’s job and installing fonts is nerd-fonts-installer’s, each reading its own config. Fluxion verifies the tool, then runs it; the checksums for what it installs live in that tool’s profile. Set spec.policy.mode: strict to get back a hard refusal of missing checksums and mutable URLs — fluxion lint says so when it is absent.

no It will not trust PATH for anything privileged.

A sudo step becomes sudo -n -- <resolved target>, where the target is a real path under a root-owned system directory with no writable ancestor.

no It will not apply as root.

There is no safe way to drop back to your account for the steps that must not end up root-owned.

no It will not prompt mid-run.

Items marked confirm need --yes up front. A run that waits for input is a run that hangs unattended.

no It will not guess.

A probe that cannot answer reports unknown, never missing. Absence of evidence is not evidence of absence, and reinstalling on that basis would be wrong.

Reruns

Running it twice is cheap

Fluxion records what worked — versions, checksums — and fingerprints each phase's configuration. A completed phase is skipped only while that fingerprint still matches, so editing a package list makes the phase run again rather than being quietly considered done.

fluxion status

What is installed, missing, unknown, or drifted — probed against the real host.

fluxion diff

Only what differs from this machine. The short list you actually read.

fluxion explain --item git

Why one phase or item would run or skip, in the orchestrator's own terms.

Registries

Share profiles between machines

Keep the profiles you want everywhere in a git repository, and install them by id.

The clone lives in your cache directory and is disposable. What you install lives in your config directory and is yours — a sync refreshes the first and never touches the second, and tells you which of your configurations changed upstream.

Installing writes a file and stops. Running it stays a separate, deliberate step.

fluxion remote-ls
$ fluxion registry add https://github.com/you/profiles
 Registered profiles (https://github.com/you/profiles)
  syncing…
 3 configurations available

$ fluxion remote-ls
example-profiles (profiles)
  Bootstrap configurations, one entry per role

base       Base tools             current
developer  Developer workstation  update available
server     Headless server        not installed

$ fluxion registry install developer --with-requires
 Installed base → ~/.config/fluxion/registries/…
 Installed developer → ~/.config/fluxion/registries/…

Review before running:
  fluxion dry-run -c ~/.config/fluxion/…/developer.yaml
One schema

A graph of phases, selected by the host

spec.phases

Phases declare dependencies, so ordering is a graph you can read and render — fluxion graph emits Mermaid, DOT, or JSON.

when

Every phase and step can be selected by host facts. The same profile does the right thing on Fedora and on Arch, and says what it skipped.

One document shape, one validation path, one page describing it.

Reference

Read-first by design

The safe commands come first. The one that changes anything comes last.

generateA starter profile for this machine
validateWould this profile run at all?
lintProfile quality and safety advice
doctorIs this host ready for this profile?
planThe execution plan — text, table, tree, or JSON
graphThe phase dependency graph (Mermaid, DOT, JSON)
status · diff · explainWhat is installed, what differs, and why
dry-runThe real traversal with mutation switched off
applyDo it
registry · remote-lsProfiles shared through a git repository
snapshot · importTurn what is installed into a profile
state · reportInspect what previous runs recorded
Documentation

Everything is written down

History

Upgrading from the Java version

Fluxion was a Java 25 / GraalVM project. This is a ground-up Crystal reimplementation of the same product: same commands, same trust rules. State files written by the Java version are read directly, so upgrading does not mean reinstalling everything you already have.