This repository contains a complete, declarative configuration for a minimal and powerful desktop environment on NixOS. It fuses the minimalist philosophy of the suckless.org toolset with the reproducible and robust system management of NixOS, using Flakes and Home Manager. The primary development environment is a terminal-based Emacs, configured for a first-class interactive Clojure workflow.
The core principle is to treat the manually prepared Suckless source code as the definitive input for the system build. All patching and config.def.h customization is done by you, directly on the source files, before invoking the Nix build. Nix then takes these pre-customized sources and builds them within a pure environment, resulting in a fully reproducible, custom-tailored desktop environment.
- Core Philosophy
- Features
- System Structure
- The Declarative Suckless Build Process
- Key Configuration Details
- Installation and Replication
- Daily Workflow
This setup is born from two ideals:
- Suckless: Software that is simple, minimal, and does one thing well. The configuration is done by patching and editing the C source code directly.
- NixOS: A Linux distribution where the entire system configuration—from the kernel to packages to dotfiles—is defined in a set of declarative files. Builds are reproducible and atomic.
By combining them, we achieve the ultimate goal: a system where even our custom-patched window manager and terminal, alongside a fully configured Emacs IDE, are just another part of a single, version-controlled, reproducible configuration.
- Fully Declarative: The entire system is managed by the Nix Flake in this repository.
- Custom Suckless Stack:
dwm,st,dmenu, andslstatusare all built from user-customized local source code. - Modern Emacs IDE: A minimal, terminal-based Emacs (
emacs-nox) setup with powerful, discoverable keybindings and a focus on interactive Clojure development with CIDER. - Shared Development Toolchain: Language servers (
clojure-lsp,ruff,nil) and formatters are managed by NixOS and shared between all tools. - Robust, Daemon-less GTK Theming: A clean, declarative solution ensures GTK2, GTK3, and GTK4 applications are themed correctly without relying on daemons.
- Home Manager: Manages all user-level configuration, including dotfiles, packages, services, and the Emacs configuration itself.
- Minimalist Session Management: Uses a declarative
~/.xinitrcfile to launch thedwmsession viastartx.
The repository is organized to clearly separate concerns, with a dedicated directory for the Emacs configuration.
.
├── flake.nix # The central entry point for the entire system build.
├── configuration.nix # System-level NixOS settings (kernel, packages, etc.).
├── users/
│ └── blfnix.nix # User-level config via Home Manager (packages, services).
├── suckless-configs/ # Raw source code for the suckless tools. Edit config.def.h here!
│ └── ...
├── dotfiles/ # Static configuration files managed by Home Manager.
│ └── emacs/ # Modular Emacs configuration in Lisp.
│ ├── init.el
│ └── lisp/
│ ├── clojure.el
│ ├── keybinds.el
│ ├── langs.el
│ └── ui.el
└── assets/ # Screenshots for the README.
└── ...
flake.nix: Defines the project's inputs (nixpkgs, home-manager) and orchestrates the build.configuration.nix: Defines the machine, including system-wide packages, fonts, and security settings.users/blfnix.nix: Defines the user environment, containing the Suckless build logic and installing all user-level packages like Emacs and its language tools.suckless-configs/: Holds the source code for each suckless tool, which you modify directly.dotfiles/emacs/: Contains the modular Emacs configuration, which is symlinked into~/.config/emacsby Home Manager.
The magic happens in users/blfnix.nix. A custom Nix function builds the suckless tools from your manually prepared source code.
- Your Role (Manual Preparation): Before building, you directly modify the source code in the
suckless-configs/directory. This includes editingconfig.def.hand applying patches. - Nix's Role (Reproducible Build): After your preparation,
nixos-rebuild switchexecutes the Nix derivation, compiling your customized code in a pure environment.
This configuration achieves consistent GTK theming without background services by:
- Installing core GTK libraries system-wide.
- Using Home Manager to write
settings.inifiles. - Setting the
GTK_THEMEenvironment variable to forcefully override application themes.
The Emacs setup is a core part of this workflow, designed to be powerful yet minimal.
- Installation:
emacs-noxis installed viahome.packagesfor a terminal-only experience. All required language servers (clojure-lsp, etc.) are also installed here, making them available system-wide. - Configuration: The configuration is written in modular Emacs Lisp files within
dotfiles/emacs/. Home Manager links this directory to~/.config/emacs. - Keybindings: A modern, non-modal keybinding scheme is implemented using a
Spaceleader key, with thewhich-keypackage providing discoverable pop-up menus. This makes the powerful features of Emacs accessible without memorizing obscure key chords. - Clojure Focus: The environment is tailored for interactive Clojure development using CIDER, the de-facto standard REPL-driven development tool.
This configuration includes several non-default settings for improved security and performance, including kernel parameter hardening and automatic Nix store optimization.
To use this configuration on your own machine:
- Prerequisites: You need a working NixOS installation with Flakes enabled.
- Clone the Repository:
git clone https://github.com/bengtfrost/NixOS-with-Suckless.git - Adapt for Your Hardware: CRITICAL: Replace
hardware-configuration.nixwith the one from your machine. - Adapt for Your User: Update usernames in
flake.nix,configuration.nix, andusers/blfnix.nix. - Build the System:
sudo nixos-rebuild switch --flake .#nixos
- To change a
dwmkeybinding: Editsuckless-configs/dwm/config.def.h, then runsudo nixos-rebuild switch --flake .. - To change Emacs behavior: Edit the relevant
.elfile indotfiles/emacs/, then restart Emacs. - To add a new application: Add it to
home.packagesinusers/blfnix.nix, then runhome-manager switch --flake .. - Clojure Development: Open a
.cljfile in Emacs, runM-x cider-jack-into start the interactive REPL, and evaluate code directly from your editor.
This configuration is provided under the MIT License.

