docs: update readme

This commit is contained in:
Youwen Wu 2025-01-16 17:10:06 -08:00
parent 01afc09c18
commit ef7beee001
Signed by: youwen5
GPG key ID: 865658ED1FE61EC3

278
README.md
View file

@ -1,203 +1,129 @@
# liminalOS # liminalOS
This is a repository that implements liminalOS, my personal Linux distribution This is a repository that implements liminalOS, my personal Linux distribution
based on [NixOS](https://nixos.org/). based on [NixOS](https://nixos.org/). The most overengineered personal
computing environment, ever. Imagine having to `vim` into source code and
Time wasted writing Nix code: recompile an entire operating system to change a font. Yes, I use this on a
![](https://wakatime.com/badge/user/018dc5b8-ba5a-4572-a38a-b526d1b28240/project/c59b3d5e-0c9c-4bd5-a752-e75522ab0cdc.svg) + [![wakatime](https://wakatime.com/badge/user/018dc5b8-ba5a-4572-a38a-b526d1b28240/project/de5e82f8-8a09-42cb-ae45-9c80f2ab5a41.svg)](https://wakatime.com/badge/user/018dc5b8-ba5a-4572-a38a-b526d1b28240/project/de5e82f8-8a09-42cb-ae45-9c80f2ab5a41) daily basis.
This repository exposes a NixOS module that declares the entire liminalOS This repository exposes a NixOS module that declares the entire liminalOS
operating system. It aims to be an easy way to both set up a brand new system operating system. It aims to be an easy way to both set up a brand new system
with my opinionated configurations, and also inject into an existing NixOS with my opinionated configurations, and also inject into an existing NixOS
configuration. configuration.
Reference implementations of liminalOS on actual working systems is in My reference implementations of liminalOS on actual working systems are
[./reference](./reference). available [here](./reference).
liminalOS is currently in a heavily experimental state, but it is used in liminalOS is currently in a heavily experimental state, but it is used in
production every day! production every day!
You can try it with `nix flake init -t github:youwen5/liminalOS#liminalOS`, You can try it with `nix flake init -t github:youwen5/liminalOS`, which will
which will create a sample configuration flake along with corresponding files. create a sample configuration flake along with corresponding files. Keep in
mind you'll have to do a little bit of work in these files to get a working
system configuration. Some Nix knowledge is expected, but comments are there to
help!
Many have written at length about the virtues of NixOS and _declarative ```
configuration_ and _immutability_ and such. I doubt what I have to say is flowchart TB
particularly novel, but I'll leave a few thoughts about Nix and NixOS and why subgraph "Core System Layer"
they do things better anyways. In particular, instead of immediately NixOS["NixOS/Darwin Base"]
evangelizing about the virtues of Nix, I'll first motivate the reasons for why SysMod["System Modules"]:::sysmod
I chose a tool with exactly its properties, based on my use case (but not to HM["Home Manager"]:::hm
worry, the evangelizing will come later). end
Essentially: allow me to introduce you to the subgraph "Platform Modules"
origins of [NixOS God subgraph "Linux Modules"
Complex](https://www.reddit.com/r/NixOS/comments/kauf1m/dealing_with_post_nixflake_god_complex/). LinuxCore["Linux Core"]:::linux
Desktop["Desktop Environment"]:::linux
Audio["Audio System"]:::linux
Gaming["Gaming Support"]:::linux
Graphics["Graphics"]:::linux
end
If you would like advice on whether or not to use NixOS: subgraph "Darwin Modules"
DarwinCore["Darwin Core"]:::darwin
Homebrew["Homebrew"]:::darwin
WM["Window Management"]:::darwin
end
end
<details> <summary>see <a subgraph "Home Manager Layer"
href="https://github.com/hlissner/dotfiles">hlissner's</a> breakdown, CommonMod["Common Modules"]:::hmmod
reproduced below:</summary> Should I use NixOS? ShellEnv["Shell Environment"]:::hmmod
Tools["Essential Tools"]:::hmmod
Short answer: no. subgraph "Platform-Specific HM"
LinuxHM["Linux Config"]:::linux
Theming["Linux Theming"]:::linux
Hyprland["Hyprland Config"]:::linux
DarwinHM["Darwin Config"]:::darwin
end
end
Long answer: no really. Don't. subgraph "Package Management"
Packages["Custom Packages"]:::pkg
Overlays["Overlays"]:::pkg
end
Long long answer: I'm not kidding. Don't. subgraph "Host Configuration"
RefHosts["Reference Hosts"]:::host
Templates["Host Templates"]:::host
end
Unsigned long long answer: Alright alright. Here's why not: subgraph "Build System"
Flake["Flake Entry Point"]:::build
Builder["Build System"]:::build
end
Its learning curve is steep. You will trial and error your way to %% Relationships
enlightenment, if you survive the frustration long enough. NixOS is unlike NixOS --> SysMod
other Linux distros. Your issues will be unique and difficult to google. A SysMod --> LinuxCore & DarwinCore
decent grasp of Linux and your chosen services is a must, if only to HM --> CommonMod
distinguish Nix(OS) issues from Linux (or upstream) issues -- as well as to CommonMod --> ShellEnv & Tools
debug them or report them to the correct authority (and coherently). If words CommonMod --> LinuxHM & DarwinHM
like "declarative", "generational", and "immutable" don't put your sexuality in LinuxHM --> Theming & Hyprland
jeopardy, you're considering NixOS for the wrong reasons. The overhead of DarwinCore --> Homebrew & WM
managing a NixOS config will rarely pay for itself with 3 systems or fewer LinuxCore --> Desktop & Audio & Gaming & Graphics
(perhaps another distro with nix on top would suit you better?). Official Flake --> Builder
documentation for Nix(OS) is vast, but shallow. Unofficial resources and Builder --> RefHosts
example configs are sparse and tend toward too simple or too complex (and most Templates --> RefHosts
are outdated). Case in point: this repo. The Nix language is obtuse and its Packages --> Overlays
toolchain is not intuitive. Your experience will be infinitely worse if Overlays --> Builder
functional languages are alien to you, however, learning Nix is a must to do
even a fraction of what makes NixOS worth the trouble. If you need somebody
else to tell you whether or not you need NixOS, you don't need NixOS.
</details>
<hr /> %% Click Events
click SysMod "https://github.com/youwen5/liminalOS/tree/main/modules"
click LinuxCore "https://github.com/youwen5/liminalOS/tree/main/modules/linux/core"
click DarwinCore "https://github.com/youwen5/liminalOS/tree/main/modules/darwin"
click HM "https://github.com/youwen5/liminalOS/tree/main/hm"
click CommonMod "https://github.com/youwen5/liminalOS/tree/main/hm/modules/common"
click ShellEnv "https://github.com/youwen5/liminalOS/tree/main/hm/modules/common/shellenv"
click Tools "https://github.com/youwen5/liminalOS/tree/main/hm/modules/common/essentials"
click Desktop "https://github.com/youwen5/liminalOS/tree/main/modules/linux/desktop-environment"
click Audio "https://github.com/youwen5/liminalOS/tree/main/modules/linux/audio"
click Gaming "https://github.com/youwen5/liminalOS/tree/main/modules/linux/gaming"
click Graphics "https://github.com/youwen5/liminalOS/tree/main/modules/linux/graphics"
click Homebrew "https://github.com/youwen5/liminalOS/blob/main/modules/darwin/homebrew.nix"
click WM "https://github.com/youwen5/liminalOS/blob/main/modules/darwin/yabai.nix"
click RefHosts "https://github.com/youwen5/liminalOS/tree/main/reference/hosts"
click Templates "https://github.com/youwen5/liminalOS/tree/main/templates/minimal"
click Packages "https://github.com/youwen5/liminalOS/tree/main/pkgs/by-name"
click Overlays "https://github.com/youwen5/liminalOS/tree/main/overlays"
click Theming "https://github.com/youwen5/liminalOS/tree/main/hm/modules/linux/theming"
click Hyprland "https://github.com/youwen5/liminalOS/tree/main/hm/modules/linux/desktop-environment/hyprland"
click Builder "https://github.com/youwen5/liminalOS/blob/main/lib/buildLiminalOS.nix"
click Flake "https://github.com/youwen5/liminalOS/blob/main/flake.nix"
<!-- prettier-ignore --> %% Styling
> **lim·i·nal** classDef default fill:#f9f9f9,stroke:#333,stroke-width:2px;
> 1. between or belonging to two different places, states, etc. classDef sysmod fill:#a8d1f0,stroke:#333;
classDef hm fill:#b8e6b8,stroke:#333;
The goal of liminalOS is to allow my computing environment to exist in classDef hmmod fill:#d1f0a8,stroke:#333;
different computers at the same time, and to be absolutely unbreakable while classDef linux fill:#f0a8a8,stroke:#333;
doing so. Let's talk about existing in multiple computers first, or otherwise classDef darwin fill:#f0d1a8,stroke:#333;
known as some form of "settings sync". To the typical user, stuck in the classDef pkg fill:#d1a8f0,stroke:#333;
_imperative world_, this sounds unrealistic at worst, and janky at best. classDef host fill:#a8f0d1,stroke:#333;
Generally, people encounter environment or settings syncing in two ways: either classDef build fill:#f0f0a8,stroke:#333;
the entire service is ran in the cloud, so it's really the _same_ environment ```
accessed from multiple places, or it's some often half baked opaque solution
involving you making an account and sending all your settings to a sync server
(see: Mozilla Firefox).
The more technically minded may instead opt to create a "dotfiles" repository,
holding their vast corpus of meticulously crafted configuration files. These
repos often come with a janky `install.sh` that does its best to throw all the
files into the correct place. This usually works the first time, but trying to
keep the installed dotfiles in sync with a central repository is a whole other
problem.
But these solutions are generally used for singular services or applications.
Keeping an entire _system_ synced up across computers down to the minute
configurations and applications seems incredibly unwieldy, through our usual
conception of how we interact with our operating systems.
The more obsessive system tweakers might try a dotfile manager like `chezmoi`
or GNU Stow. I have not tried these so I make no judgements on their utility
for their intended purpose, but generally these solutions miss a key feature:
they provide the configuration, but don't install the software. But the
software and the configuration are fundamentally tied together; these are not
concerns to be separated. If the software is installed, it almost always needs
to be configured anyways. If the configuration exists, the software should be
installed. These solutions may work well for managing configuration, but they
have the same issue as before: you also need to install the software you're
configuring!
So, *nix hackers reach for things like [Ansible](https://www.ansible.com/), that
promise automatic configuration of entire systems. Though Ansible was designed
to deploy cloud servers quickly through the Infrastructure-as-Code approach,
some people opt to use it for deploying their systems quickly as well. I have
not tried it, but from what I've heard, it works fine for simple deployment but
gets quite unwieldy for more complex purposes (especially for personal systems,
which aren't expected to be as ephemeral as servers).
If you agree with the premises I've laid out up to this point, you might come
to the conclusion that I've made: to solve this issue, we need a solution that
does _all of it_. A unified tool for deploying software and managing systems.
And it must necessarily be declarative and reproducible, because that is the
only way to sanely manage a system. Imagine working on a programming project
where recompiling with the same source code would non-deterministically produce
different results based on the environment!
Well, [Nix](https://nixos.org/) is the _purely functional_ package manager
(i.e. declarative, reproducible), and NixOS is a Linux distribution that is
managed entirely by Nix. Essentially, Nix provides a solution to the problem of
_software deployment_, and in fact was purpose built to do so in Eelco
Dolstra's seminal [PhD
thesis](https://edolstra.github.io/pubs/phd-thesis.pdf). NixOS is a system that
takes the power of Nix and applies it to declaratively configure an _entire
Linux system_. All of the software can be specified precisely using the Nix
expression language, a purely functional DSL used by Nix. And alongside the
software, it also configures it, effectively acting as a dotfile manager.
Indeed, many core NixOS services and a wide range of programs can be set up
through _NixOS modules_, where the program is installed and configured in the
same place. (and many programs like `fzf`, `btop`, etc have similar
corresponding `home-manager` modules).
NixOS is also _immutable_, which means that the system cannot be modified after
it is built from the Nix files that declare it. How do you make changes to the
system then? Obviously, we just create a new system where the changed programs
and files are included, and the old ones are removed. But they are not deleted
from the hard drive, they still exist in the _Nix store_. So, the system can
provide precise atomic rollbacks between each "generation" of itself. Broke
your GRUB configuration so your system won't boot? Messed up your kernel
settings? Just select an older working generation from the boot menu and you
instantly have a working system again. You never worry about breaking things
during either routine or massive system updates.
And because the system is fully declarative, and modifying the system is done
only through modifying its Nix configuration files, you can version and sync
them up with Git. This solves the problem of keeping system environments in
sync; now, you truly only have to keep one repository of all your configuration
in sync, and all the software installation and deployment is handled for you by
a system designed precisely for that purpose.
This makes it possible for me to share common configuration between a multitude
of entirely distinct machines, including an `x86_64` desktop, an `x86_64`
laptop, an Apple Silicon Macbook running NixOS `aarch64` using [Asahi
Linux](https://asahilinux.org/), and the same Macbook running macOS with
`nix-darwin`, sharing `home-manager` configuration with NixOS. Specific
configuration necessary to adjust hardware-specific details between each
machines are isolated to the [hosts](./hosts) directory.
This works exceptionally well, evidenced by the fact that I have (almost) the
exact same environment across three separate machines, spanning two entirely
distinct CPU architectures.
In essence, the primary failure of deployment scripts, Ansible and the like is
that they are _imperative_ - they must specify precisely _how_ to set up the
system, down to minute details, whereas in a _declarative_ approach, the user
can simply specify what the system _should look like_, and abstractions take
care of the _how_. This is what NixOS does, and it gives you remote syncing,
versioning (via `git`), and rollbacks _for free_.
## Installation guide
Currently there is no streamlined installer. Please see [the reference
implementations](./reference) for an idea on how to set up a liminalOS system.
## FAQ
### This looks like a collection of NixOS configuration files and modules. What makes it a distinct distribution?
Most Linux[^1] users will agree that any self-respecting distribution must
include at least the following: installer, package manager, and some set of
default packages. Therefore, anything that implements the aforementioned items
must also be a Linux distribution.
liminalOS comes with the Nix package manager (nobody said you need a _unique_
package manager - Ubuntu and Debian are distinct distributions yet both use
`apt`), a custom desktop environment comprised of Waybar, Hyprland, rofi, as
well as various applications installed by default, and
[the means to generate an installer](https://nixos.wiki/wiki/Creating_a_NixOS_live_CD).
Therefore, liminalOS is a Linux distribution. QED.[^2]
### Should I actually install this?
Sure.
## Hosts ## Hosts