Flatwork UI NixOS desktop screenshot
Flatwork UI running on my Niri/NixOS desktop.

Flat, technical, quiet.

A NixOS desktop rice that is now reusable as a public flake:

github:jurrebuunk/flatwork-ui

.

niri / flatwork-ui / 1px

I rewrote my desktop rice into a separate flake called Flatwork UI. The idea is simple: keep the visual system in one public place, then let my NixOS config consume the whole experience instead of carrying a pile of local theme files.

There is also a tagged release with downloadable assets on the releases page.

It is built for my Niri desktop, but the important part is the design language: square geometry, warm dark surfaces, thin structural borders, serif/mono typography, and muted technical blue.

0px radiusNo pills, no rounded tabs, no bubbly UI.
1px bordersStructure comes from lines instead of shadows.
muted accentBlue-gray interaction color, not neon cyberpunk.
serif / monoHuman labels and machine values get different voices.

The style

The default palette is dark, but not pure black. The base color is a warm almost-black, with slightly raised surfaces and a desaturated blue accent.

background


#1b1818

surface


#252121

surfaceAlt


#302b2b

text


#c4c1c1

accent


#8aa1a8

focus


#a5bbc2

soft


#9fc7c4

highlight


#d7ffc3

Typography is probably the biggest part of the personality. STIX Two Text gives the desktop a slightly academic, human feel. IBM Plex Mono keeps the technical bits crisp.

STIX Two Text

Human interface

IBM Plex Mono

/nix/store


13:37:42

The goal is not to look retro. It is modern first, but with some workstation discipline: compact spacing, clear focus states, quiet colors, and no decorative softness.

The technical shape

The theme itself is just a Nix value. That makes the desktop feel less like a folder of dotfiles and more like a small design system.

# in another flake
flatwork-ui = {
  url = "github:jurrebuunk/flatwork-ui";
  inputs.nixpkgs.follows = "nixpkgs";
};

Then my NixOS config passes the theme into both NixOS and Home Manager:

specialArgs = {
  inherit inputs;
  theme = inputs.flatwork-ui.lib.themes.default;
};

home-manager.extraSpecialArgs = {
  inherit inputs;
  theme = inputs.flatwork-ui.lib.themes.default;
};

And instead of rebuilding every app config by hand, the full Home Manager experience is imported from the flake:

imports = [
  inputs.flatwork-ui.nixosModules.fonts
  inputs.flatwork-ui.homeManagerModules.default
];

That gives me the shared styling for the desktop: GTK, Firefox, Waybar, Rofi, Mako, SwayOSD, Alacritty, Fastfetch, and the shell prompt. My main config only keeps the machine-specific pieces: Niri keybinds, monitor names, startup behavior, secrets, and host hardware.

tokenscolors, fonts, geometry, spacing
modulesHome Manager applies the experience
hostNiri, outputs, services, hardware
desktopsame visual language everywhere

Why a separate flake?

Because I want the rice to be reusable. My actual NixOS repo should describe my machine. Flatwork UI describes the look and feel.

It also means I can try theme variants without rewriting modules:

theme = inputs.flatwork-ui.lib.themes.gruvbox;
theme = inputs.flatwork-ui.lib.themes.starship;
theme = inputs.flatwork-ui.lib.themes.teal;

The default is still the one in the screenshot: warm dark background, blue-gray accent, STIX Two Text, IBM Plex Mono, square everything.

The end result

Flatwork UI is the first time my desktop rice feels like an actual product of my config instead of something layered on top of it. The design rules are centralized, the modules are reusable, and the host config is smaller.

That is the best part of NixOS rice to me: not just making the desktop look nice, but making the look reproducible.