···1+@document.meta
2+title: Welcome to Flake-Ocean
3+description: This is a static site made using norgolith.
4+authors: [
5+ ladas552
6+]
7+categories: []
8+created: 2025-11-12
9+layout: home
10+version: 1.1.1
11+@end
12+13+* Nix
14+ Hi, this is Ladas552 speaking
15+16+ You are reading beta version of docs for my NixOS config, It will explain how it works and why it works!
17+18+ Not because it's complicated, but for people to learn and grow with me.
19+20+ Have fun reading some articles, hopefully more and better down bellow.
21+22+ Feel free to ask questions to improve them to plank scale limits.
23+24+ The site is build using norgolith and tailwind css. But keep in mind, the front end was vibecoded, so don't go looking for that source code - it's pure ass.
25+26+ If you don't wanna read the whole thing just because it was build using an llm that actively destroys out planet. I can't blame you.
27+28+ But if you have some tailwind CSS or web knowledge please let me know to improve this site with human hands. Because I don't wanna maintain 2 different sites at the same time all by myself.
+15
content/posts/Flake-Parts.norg
···000000000000000
···1+@document.meta
2+title: Flake Parts
3+description: Deep dive into Nix Flakes
4+authors: ladas552
5+categories: [
6+ tutorial
7+ flakes
8+]
9+created: 2025-12-02
10+layout: post
11+draft: true
12+version: 1.1.1
13+@end
14+15+* Flake Parts
···1+@document.meta
2+title: Home Manager
3+description: Lazy house keeping service
4+authors: [
5+ ladas552
6+]
7+categories: [
8+ Home
9+ dotfiles
10+]
11+created: 2026-02-08T21:13:36+05:00
12+updated: 2026-02-08T21:13:36+05:00
13+draft: true
14+layout: post
15+version: 1.1.1
16+@end
17+18+* Home Manager
19+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
20+ labore et dolore magna aliqua. Lobortis scelerisque fermentum dui faucibus in ornare.
···1+@document.meta
2+title: Impermanence on NixOS with ZFS and tmpfs
3+description: Guide for my impermanence setup
4+authors: [
5+ ladas552
6+]
7+categories: [
8+ Impermanence
9+ ZFS
10+ Guide
11+]
12+created: 2026-01-02
13+draft: false
14+layout: post
15+version: 1.1.1
16+@end
17+18+** What is Impermanence
19+ ___
20+ It wipes your `/root` on reboot and your startup is a blank canvas, but you can persist mounts and bind mount directories from it in your normal root to save stuff like cache and tokens. So you wipe all the junk and save actually useful stuff.
21+22+ For example you can install full KDE Plasma session, run it, and if you get bored. Just disable it and no KDE junk left.
23+24+ *Important to note*: That impermanence of my setup uses tmpfs, so it writes `/root` to RAM, so nothing actually gets erased on the Disk. Meaning no continuous I/O rewrites wearing out your Drive(/not that it would mater in practice/). But the state isn't saved between reboots, as with anything on RAM
25+26+ Also when I refer to `/root`, it's actually the whole `/`, not just root user directory.
27+*** Why did you set it up
28+ ___
29+ I was bored. I don't find benefits of impermanence so crucial to completely overhaul how your system behaves and I don't trust myself to maintain it.
30+31+ But there are some benefits to it:
32+ - I only backup important files, no cache, no states, only files and media;
33+ - I always know what's on my system because it's declared in the config;
34+ - It opens up possibilities to experiment more with my system, because if I could setup impermanence and not loose all my files, I am unstoppable;
35+*** What's the meaning of writing this page?
36+ ___
37+ It's not that hard to setup impermanence, but to requires reading a lot of stuff, and if you don't use ZFS or BTRFS even full reinstall for rearranging partitions. I have read several articles, watched videos, and stole code from many GitHub repos.
38+39+ Plus most guides just go to the wipe stage right away, without saying how to persist, or how it practically works for the user to not loose their files. I will try to compete in these aspects.
40+41+*** What is your current setup?
42+ ___
43+44+ I got ZFS with tmpfs, with 2 persistence datasets. `/cache` and `/persist`. And a plaint vFAT `/boot` partition, where GRUB or Systemd-boot will put generation images.
45+46+ Most people assume you gotta have 64Gb or RAM for tmpfs to be convenient, but actually you just need a well structured disk layout. Then the tmpfs usually only takes 50MB to 100MB of RAM.
47+48+ Template structure of ZFS datasets that will be essential:
49+50+ - `/cache` is for rust targets, everything in `~/.cache`, .local states, etc.
51+52+ - `/persist` is for Media, browser profiles, Projects, etc. This is the only datasets that get's backed up by `sanoid`.
53+54+ - `/nix` for /nix/store. NixOS won't boot without it. All the files that aren't persisted, but appear on my system are symlinked from `/nix`. That includes config files and services.
55+56+ - `/tmp` for /tmp. yeah, anyways it's to not overload tmpfs when downloading something on browser. with `boot.tmp.cleanOnBoot = true;` it is cleared on boot anyways.
57+58+ tmpfs is erased on reboot, so `/` and everything below it, including `/home` is gone, unless put into `/cache` or `/persist` datasets.
59+ tmpfs is on RAM, so it can overload if exceeds certain size, to prevent that I got several more zfs datasets, that aren't persisted, meaning they don't have connection to files in other datasets, but aren't erased by default.
60+61+** What we need?
62+*** A ZFS setup
63+ This isn't a *ZFS guide* so, unless you have *ZFS setup* on your *NixOS*, you can kiss this Guide goodbye. Go read OpenZFS documentation. But here is my installation script in case you'd like more guiding. But seriously, go read docs, real engineers know a lot more than I do.
64+65+ {https://github.com/Ladas552/Flake-Ocean/blob/e460837d18f37723510f9b74c46636fd2b5b4f25/install/impermanence.norg}[permalink in the github repo, please insure the branch is up to date before checking in], it contains actual descriptions to each line as a Norg file format that you can tangle. Like bible in org mode.
66+ @code sh
67+ sudo zpool create -f \
68+ -o ashift=12 \
69+ -o autotrim=on \
70+ -O compression=zstd \
71+ -O acltype=posixacl \
72+ -O atime=off \
73+ -O xattr=sa \
74+ -O normalization=formD \
75+ -O mountpoint=none \
76+ zroot "/dev/sda2"
77+78+ sudo zfs create -o mountpoint=legacy zroot/root
79+ sudo mount -t zfs zroot/root /mnt
80+81+ sudo mount --mkdir "$BOOTDISK" /mnt/boot
82+ # All the stuff below will be explained later
83+ sudo zfs create -o mountpoint=legacy zroot/nix
84+ sudo mount --mkdir -t zfs zroot/nix /mnt/nix
85+86+ sudo zfs create -o mountpoint=legacy zroot/tmp
87+ sudo mount --mkdir -t zfs zroot/tmp /mnt/tmp
88+89+ sudo zfs create -o mountpoint=legacy zroot/cache
90+ sudo mount --mkdir -t zfs zroot/cache /mnt/cache
91+92+ sudo zfs create -o mountpoint=legacy zroot/persist
93+ sudo zfs snapshot zroot/persist@blank
94+ sudo mount --mkdir -t zfs zroot/persist /mnt/persist
95+ # All the stuff above will be explained later
96+ sudo nixos-install --no-root-password --flake "github:Ladas552/Nix-Is-Unbreakable#NixVM"
97+ @end
98+99+*** Partitions
100+ ___
101+ A new way to manage your system. NixOS.
102+103+ Tho you probably already use NixOS if you are reading this, if you don't then get out while you can.
104+105+ On a more serious note, you need ZFS setup, with 2 particular datasets.
106+ @code nix
107+ fileSystems = {
108+ "/nix" = {
109+ device = "zroot/nix";
110+ fsType = "zfs";
111+ };
112+ "/tmp" = {
113+ device = "zroot/tmp";
114+ fsType = "zfs";
115+ };
116+ };
117+ @end
118+119+ If you don't have them, but have ZFS installed, just create them using commands
120+ @code sh
121+ sudo zfs create -o mountpoint=legacy zroot/tmp
122+ sudo zfs create -o mountpoint=legacy zroot/nix
123+ @end
124+125+ This will insure that you won't delete your `/nix/store` and it stays intact between reboots. And for this particular setup the `tmp` dataset will be used so our `tmpfs` *root* will insure that it won't randomly overload.
126+127+*** Impermanence module
128+ ___
129+ The [Impermanence module]{https://github.com/nix-community/impermanence} is a NixOS flake that creates `mount binds`. The main purpose of it is to just put stuff in special `/persist` dataset, and still be able to access it from `/root` and `/home`. More about technicality of bind mounts later
130+131+ Basically you define certain directories names in it, and it creates them, then binds them to specific relevant locations, like `".config/nvim"` will be located in `~/.config/nvim`. And if you put your Neovim config there, neovim will still follow the config, but it will be located on different dataset, and won't be wiped on boot.
132+133+ Neat right? Not really, because if directory already exists, Impermanence will override that old directory with new empty one. *Don't panic*. Data isn't lost, it was just reallocated, you can delete the directory from impermanence module and it will comeback.
134+135+ That's the main reason why most people reinstall their OS if they want to use Impermanence, because it's a pain in the glands to move the files from directories before persisting it and moving things back. There are projects that circumvent that, but I didn't use them. For example: [Persist-retro]{https://github.com/Geometer1729/persist-retro}.
136+137+ Also to persist an individual file, you need to move the file, and manually copy it to persist directory. Otherwise it complains about the original file being in the way of a mount bind.
138+139+**** You forgot to tell installation instructions
140+ ___
141+ It's nix so here is just a snippet of code. Works for flakes.
142+ @code nix
143+ #flake.nix
144+ {
145+ inputs.impermanence.url = "github:nix-community/impermanence";
146+ }
147+ @end
148+ And then just import the module, like:
149+ @code nix
150+ imports = [
151+ inputs.impermanence.nixosModules.impermanence
152+ ];
153+ @end
154+155+ We will only use the `nixosModule` because I don't have standalone Home-Manager and not planning to adopt impermanence for distros outside of NixOS.
156+157+ I have seen people use impermanence module on non flake setups, but I am not so interested in them to find and link a good one.
158+*** Immutable users
159+ ___
160+ As we delete everything in `/root`, it means passwords for users, and most importantly `root` user will be deleted.
161+162+ So just make them immutable. You can store the password file in sops, or just provide raw path from `/persist` directory.
163+164+ @code nix
165+ {
166+ # setup immutable users for impermanence
167+168+ # silence warning about setting multiple user password options
169+ # https://github.com/NixOS/nixpkgs/pull/287506#issuecomment-1950958990
170+ # Stolen from Iynaix https://github.com/iynaix/dotfiles/blob/4880969e7797451f4adc3475cf33f33cc3ceb86e/nixos/users.nix#L18-L24
171+ options = {
172+ warnings = lib.mkOption {
173+ apply = lib.filter (
174+ w: !(lib.hasInfix "If multiple of these password options are set at the same time" w)
175+ );
176+ };
177+ };
178+179+ config = {
180+ # disabling user mutability
181+ users.mutableUsers = false;
182+183+ # defining regular user, ME!
184+ users.users.ladas552 = {
185+ isNormalUser = true;
186+ description = "Ladas552";
187+ extraGroups = [
188+ "networkmanager"
189+ "wheel"
190+ ];
191+ initialPassword = "pass";
192+ # Use a path or your encryption method here
193+ hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
194+ };
195+196+ nix.settings.trusted-users = [ "ladas552" ];
197+198+ # Setting root user
199+ users.users.root = {
200+ initialPassword = "pass";
201+ hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
202+ };
203+ };
204+ }
205+ @end
206+207+ Other features for immutable users:
208+ - Can use `--no-root-password` flag in `nixos-install` command. Meaning you don't ever have to monitor it, it will install password automatically.
209+ - Can't use `passwd <user>` command. So if you mess up your password path the first time, you have to reboot to previous generation to set it correctly.
210+211+ The `initialPassword` is set as plain text because it suppose to be a backup if sops decryption failed, so you won't leave with useless system state. Otherwise, it's unused and won't have security implications for your host.
212+213+*** When do we start deleting stuff?
214+ ___
215+ Not so fast bakaru, we first need to save our stuff.
216+217+ So you need to create persisted directories
218+ @code sh
219+ sudo zfs create -o mountpoint=legacy zroot/persist
220+ sudo zfs create -o mountpoint=legacy zroot/cache
221+ @end
222+223+ And now we add them to be mounted on boot
224+ @code nix
225+ # persist mount
226+ fileSystems."/persist" = {
227+ device = "zroot/persist";
228+ fsType = "zfs";
229+ # so it's required to boot, and you won't reboot into empty desktop
230+ neededForBoot = true;
231+ };
232+233+ # cache are files that should be persisted, but not to snapshot
234+ # e.g. npm, cargo cache etc, that could always be redownload
235+ "/cache" = {
236+ device = "zroot/cache";
237+ fsType = "zfs";
238+ neededForBoot = true;
239+ };
240+ @end
241+242+ I also recommend setting up backups with sanoid if you didn't already.
243+244+ @code nix
245+ services.sanoid = {
246+ enable = true;
247+ # if you have sanoid options somewhere else, lib.mkForce
248+ # will override anything, so you only have snapshots that matter
249+ datasets = lib.mkForce {
250+ "zroot/persist" = {
251+ hourly = 50;
252+ daily = 15;
253+ weekly = 3;
254+ monthly = 1;
255+ };
256+ };
257+ };
258+ @end
259+260+ Now we have basic datasets that will store out stuff, Impermanence can wait now, we need to assign bind mounts for directories and files!
261+262+ Don't know what bind mounts are? Well simply put. They are mounts that make some directory to appear in normal location, but actually it's in a different dataset all together.
263+264+ So for example: `/home/alice225/Downloads` will be deleted on boot. But, not it's content. On the next boot, the content of `Downloads` that is in `/persist` dataset will remount itself to `/home/alice225/Downloads` path.
265+266+ It will appear seamless to other applications and to yourself. But now you can access the same files in both `/home/alice225/Downloads` and in `/persist/home/alice225/Downloads`. And remember, it is *not a symlink*. Symlinks fool programs, while bind mounts genuinely make files accessible in several locations. But be careful, because they share permissions, and can also be deleted.
267+268+*** Okay, we have locations, let's move some files into them
269+ ___
270+ So, with Impermanence module, there are some options available. Simplest approach would be to use it directly
271+272+ @code nix
273+ environment.persistence = {
274+ # one of out datasets
275+ "/persist" = {
276+ # useful option
277+ hideMounts = true;
278+ directories = [
279+ # absolute path to directories in string values
280+ "/var/log"
281+ "/var/lib/nixos"
282+ "/etc/NetworkManager/"
283+ ];
284+ };
285+ };
286+ @end
287+288+ Now you are able to just define your paths as normal and save them. But this is just normal impermanence, This blog post is about *My* setup specifically, so how about we add some abstractions to the vanilla scheme.
289+290+**** New options
291+ ___
292+ `directories` and `files` in impermanence module are just a list of string, so we can make pseudo options to add more strings to the list and `++` them with actual persistence option, or just reference our list.
293+294+ It will make it easier to define directories under different scopes. For example, setting files in `home.nix` file, but they will be used in `configuration.nix` file.
295+296+ @code nix
297+ {lib,...}:
298+ {
299+ options = {
300+ # options to put directories in, persistence but shortened
301+ # stolen from @iynaix
302+ root = {
303+ directories = lib.mkOption {
304+ type = lib.types.listOf lib.types.str;
305+ default = [ ];
306+ description = "Directories to persist in root filesystem";
307+ };
308+ files = lib.mkOption {
309+ type = lib.types.listOf lib.types.str;
310+ default = [ ];
311+ description = "Files to persist in root filesystem";
312+ };
313+ cache = {
314+ directories = lib.mkOption {
315+ type = lib.types.listOf lib.types.str;
316+ default = [ ];
317+ description = "Directories to persist, but not to snapshot";
318+ };
319+ files = lib.mkOption {
320+ type = lib.types.listOf lib.types.str;
321+ default = [ ];
322+ description = "Files to persist, but not to snapshot";
323+ };
324+ };
325+ };
326+ home = {
327+ directories = lib.mkOption {
328+ type = lib.types.listOf lib.types.str;
329+ default = [ ];
330+ description = "Directories to persist in home directory";
331+ };
332+ files = lib.mkOption {
333+ type = lib.types.listOf lib.types.str;
334+ default = [ ];
335+ description = "Files to persist in home directory";
336+ };
337+ cache = {
338+ directories = lib.mkOption {
339+ type = lib.types.listOf lib.types.str;
340+ default = [ ];
341+ description = "Directories to persist, but not to snapshot";
342+ };
343+ files = lib.mkOption {
344+ type = lib.types.listOf lib.types.str;
345+ default = [ ];
346+ description = "Files to persist, but not to snapshot";
347+ };
348+ };
349+ };
350+ };
351+ }
352+ # Holy cow nix is indented to all suns
353+ @end
354+355+ You can add more options if need be. In this we only define lists for `/persist` and `/cache`, but they are separated into `root` and `home`. So add `root` and `home` options to `nixocConfiguration` and add only `home` to home-manager for example.
356+357+ `home` is just a simple way to separate directories in `/home/ladas552` from just `/`.
358+359+ But, you know, I use flake-parts and I don't need to add these options to different files and scope. I can just inherit them all in one file!
360+361+ @code nix
362+ { lib, ... }:
363+ # link to snippet in my config
364+ # https://github.com/Ladas552/Flake-Ocean/blob/85ee207aa2e5e0d2e44aad0a0818a533ceca72cf/modules/nixosModules/Impermanence/imp-options.nix
365+ {
366+ flake.modules =
367+ let
368+ # options to put directories in, persistence but shortened
369+ # stolen from @iynaix
370+371+ root = {};
372+ home = {};
373+ # Same thing as above
374+ in
375+ {
376+ nixos.options.options.custom.imp = { inherit root home; };
377+ hjem.options.options.custom.imp = { inherit home; };
378+ homeManager.options.options.custom.imp = { inherit home; };
379+ };
380+ }
381+ @end
382+383+ This code block is from my Dendrithic config with several module classes. So each `nixos`, `hjem` and `homeManager` classes have their own `options` module that inherit the same type of options in each module scope.
384+385+ You probably didn't get any of that, but you don't need to tbh. My setup is My setup, do whatever you want.
386+387+**** Persist in action
388+ ___
389+ Now we can define some important directories and files to persist
390+ @code nix
391+ custom.imp = {
392+ root = {
393+ directories = [
394+ "/etc/NetworkManager/"
395+ "/var/lib/NetworkManager"
396+ "/var/lib/iwd"
397+ ];
398+ };
399+ home = {
400+ directories = [
401+ ".librewolf"
402+ ];
403+ cache = {
404+ files = [ ".local/share/com.jeffser.Alpaca/alpaca.db" ];
405+ directories = [
406+ ".local/share/nvim"
407+ ".local/state/nvim"
408+ ".config/libreoffice"
409+ ".cache/librewolf"
410+ ".cache/keepassxc"
411+ ".config/keepassxc"
412+ ".cache/nix"
413+ ".cache/nix-index"
414+ ];
415+ };
416+ };
417+ };
418+ @end
419+420+ But if you set this thing up, and rebuild it wouldn't do a thing. Remember, these options and list are just place holders. Meant to be easy to write and read. Now we gotta add them to an actual Impermanence module options.
421+422+ @code nix
423+ { lib, config, ... }:
424+ let
425+ cfg = config.custom.imp;
426+ # config.custom.meta.user is just my placeholder for `username`
427+ # just hard code the value, or replace it with your own solution to select a user
428+ cfghm = config.home-manager.users."${config.custom.meta.user}".custom.imp;
429+ cfghj = config.hjem.users."${config.custom.meta.user}".custom.imp;
430+ in
431+ {
432+ environment.persistence = {
433+ "/persist" = {
434+ hideMounts = true;
435+ # referencing files via our abstraction option
436+ files = lib.unique cfg.root.files;
437+ directories = lib.unique (
438+ # here you can define directories normally
439+ [
440+ "/var/log"
441+ "/var/lib/nixos"
442+ ]
443+ # and concatenate too!
444+ ++ cfg.root.directories
445+ );
446+ # add persists to `/home/user` path
447+ users."${config.custom.meta.user}" = {
448+ files = lib.unique ([ ] ++ cfghm.home.files ++ cfghj.home.files);
449+ directories = lib.unique (
450+ [ ] ++ cfg.home.directories ++ cfghm.home.directories ++ cfghj.home.directories
451+ );
452+ };
453+ };
454+ # same as above
455+ "/cache" = {
456+ hideMounts = true;
457+ files = lib.unique cfg.root.cache.files;
458+ directories = lib.unique cfg.root.cache.directories;
459+ users."${config.custom.meta.user}" = {
460+ files = lib.unique (cfg.home.cache.files ++ cfghm.home.cache.files ++ cfghj.home.cache.files);
461+ directories = lib.unique (
462+ cfg.home.cache.directories ++ cfghm.home.cache.directories ++ cfghj.home.cache.directories
463+ );
464+ };
465+ };
466+ };
467+ }
468+ @end
469+470+ You will need to adjust this code snippets to your own config. For example, if you don't use `hjem`. And replace `config.custom.meta.user` with your own username.
471+472+ I am not stating this approach is the best, but it just how I ended up using Impermanence module, and it might be useful for you to know.
473+474+ Now upon rebuild Impermanence module should add all the interesting directories to datasets and establish bind mounts.
475+476+ Wait, did we forget something? Uhhh...
477+478+*** DELETE ERASE REDUCTED
479+ ___
480+ @code nix
481+ # replace the root mount with tmpfs
482+ # wipes everything if you don't have proper persists, be warned
483+ fileSystems."/" = lib.mkForce {
484+ device = "tmpfs";
485+ fsType = "tmpfs";
486+ neededForBoot = true;
487+ options = [
488+ "defaults"
489+ # whatever size feels comfortable, smaller is better
490+ "size=1G"
491+ "mode=755"
492+ ];
493+ };
494+ @end
495+496+ This is all you need. So simple in comparison to the whole page above, right?
497+498+ The main reasons for that are:
499+ - It's harder to keep what you have gained, but trivial to loose everything you ever had;
500+ - Also the `size=1G` wouldn't make it possible to use tmpfs as a main without persists and bind mounts. Bind mount only makes files accessible in 2 locations, but only stored in ZFS dataset.
501+502+ This should be all you need to start using tmpfs for impermanence on ZFS.
503+504+ There are some niceties I want to share tho, to make your life easier.
505+506+*** Some sprinkles to your epitome of agony
507+**** Snippets
508+ ___
509+ Set this so you aren't lectured by `you know what you are doing` lecture from sudo every boot
510+ @code nix
511+ security.sudo.extraConfig = "Defaults lecture=never";
512+ @end
513+514+ If you use {https://github.com/Mic92/sops-nix}[sops-nix], set ssh paths to `/persist` because otherwise `nixos-install` won't find the keys.
515+ @code nix
516+ sops.age.sshKeyPaths = [
517+ "/persist/home/vimjoyer/.ssh/ssh-key"
518+ ];
519+ sops.age.keyFile = lib.mkDefault "/persist/home/vimoyer/.config/sops/age/keys.txt";
520+ @end
521+522+**** Persist everything
523+ ___
524+ Persist every bit that might be useful to you, tokens, cookies and all that if they matter to you. Depending on the application, you might wanna persist only one file. But for something like steam, it compiles shader cache, which is persistable with this snippet
525+ @code nix
526+ # persist steam
527+ custom.imp.home = {
528+ cache.directories = [
529+ ".local/share/Steam"
530+ ".cache/mesa_shader_cache"
531+ ".cache/mesa_shader_cache_db"
532+ ".cache/radv_builtin_shaders"
533+ ];
534+ };
535+ @end
536+537+ But how would you know what to persist? Well, first you might want to look at others people config files. Because the best way to avoid pit falls is following the walked road.
538+539+ Some pretty extended persist list can be found in following configurations:
540+ - {https://github.com/search?q=repo%3Aiynaix%2Fdotfiles+custom.persist&type=code}[Iynaix dotfiles];
541+ - {https://github.com/saygo-png/nixos}[Saygo's config];
542+ - {https://github.com/xarvex/dotfyls}[Xarvex dotfyls];
543+544+ If they don't use the same modules as you, figure it out on your own. Most of the time programs follow xdg conventions and store files in `.config .cache .local/state .local/share`. Or instead of persisting the settings, symlink raw files.
545+546+**** Credits and suggestions
547+ ___
548+ You can suggest anything you'd like to add to {*** Some sprinkles to your epitome of agony}. Cool configs using impermanence, tips, snippets and so on. Just ping me on Discord or write an issue on github. Your username will be added below as a privilege for being so awesome!
549+550+ List of awesome people:
551+ - *Iynaix*'s impermanence abstraction structure and ZFS setup
552+ - *Vimjoyer*'s Impermanence video introducing basic concept to me
553+ - *talyz* for making Impermanence module and extensive readme for the project
554+ - *Graham* for {https://grahamc.com/blog/erase-your-darlings/}
555+ - *Willbush* for {https://willbush.dev/blog/impermanent-nixos/}
556+ - *Elis Hirwing* for {https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/}
557+ - {https://github.com/fliplus}[Flipus] and *snohater* for providing feedback on readability of the thing.
558+ - *You* for reading this all, good luck with your NixOS config. Hope this article helped you the same way all the people mentioned above helped me. Without such a vast community, I wouldn't be able to figure all these things out. And I didn't reinvent a wheel, it's all the work of Open Source contributors. So, hopefully you also share your knowledge in the future. Improve on what's old or reduce it to atoms, it's up to you. It's your setup, and only for you to decide, whether you really want to setup it up.
···1+@document.meta
2+title: Nvfetcher
3+description: Inputs outside of flakes
4+authors: [
5+ ladas552
6+]
7+categories: [
8+ inputs
9+ un-flake
10+]
11+created: 2026-02-08
12+draft: false
13+layout: post
14+version: 1.1.1
15+@end
16+17+** What is Nvfetcher?
18+ It's a Haskell program that takes values from a toml file and generates fetched inputs that I can use in my config. Without having to manually update the Hash, but still remain locked on per commit basis. Same as `flake.lock`.
19+** Why don't you just use flakes?
20+ Even tho I love flakes, I can acknowledge that they have issues. Namely, in the context of inputs:
21+ - Unchanged `follows` for inputs will download unnecessary code, that in context of something big as nixpkgs can cost 40MiB of download data per input and per `nix flake update`;
22+ - You can't define inputs to download stuff only when needed. The `ghostty-shaders` input will be downloaded during update on both Desktop, a server and even on the phone. Can't decide whether it's needed there or not;
23+ - Inputs are hella slow. No, I am not benchmarking it, just feels like this.
24+25+ In this case, Nvfetcher comes in handy. Fetchers work only if you import the input.
26+*** What about Npins?
27+ I don't like using cli interface to generate fetches. Also It has problems with AppImages.
28+** How to use Nvfetcher?
29+ Go read the docs in the {https://github.com/berberman/nvfetcher}[project's repository].
30+31+ TLDR: define source and fetcher in toml file, 2 files are generated, you import nix file with `pkgs.callPackage`, or read json file directly with `builtins.fromJSON` and `builtins.readFile` if `pkgs` isn't available on the scope, or you want to import a fetched nix file inside of your nix module.
32+33+ For example, it works wonders for fetching neovim plugins.
34+ @code nix
35+ # nvfetcher pins
36+ sources = pkgs.callPackage "${self}/_sources/generated.nix" { };
37+ heirline-components = pkgs.vimUtils.buildVimPlugin {
38+ name = "heirline-components.nvim";
39+ doCheck = false;
40+ src = sources.heirline-components.src;
41+ };
42+ @end
43+44+ Then I can call `heirline-components` in a package list to install it. I use `self` to avoid using relative paths, and keep my config modules independent of location.
45+46+ And here is a custom example of using the json file directly.
47+48+ @code nix
49+ sourcesJson = builtins.fromJSON (builtins.readFile ./_sources/generated.json);
50+51+ modules = builtins.mapAttrs (
52+ name: value:
53+ let
54+ src = fetchTarball {
55+ url = "${value.src.url}/archive/${value.src.rev}.tar.gz";
56+ sha256 = value.src.sha256;
57+ };
58+ in
59+ value // { inherit src; }
60+ ) sourcesJson;
61+ @end
62+63+ This snippet is in my `flake.nix`. I use it to create a `specialArgs` in my config called `modules`. In any file I can add `modules` to the top and import some file from Nvfetcher inputs.
64+65+ Demonstration of one of my hosts that is NixOS-WSL based.
66+67+ @code nix
68+ { modules, ... }:
69+ {
70+ flake.modules.nixos.NixwsL =
71+ { config, ... }:
72+ {
73+ imports = [
74+ "${modules.nixos-wsl.src}/modules"
75+ ];
76+ networking.hostName = "NixwsL";
77+ wsl = {
78+ enable = true;
79+ # if you are wondering what these config options are
80+ # it will be explained in another article
81+ defaultUser = "${config.custom.meta.user}";
82+ startMenuLaunchers = true;
83+ tarball.configPath = "${config.custom.meta.self}";
84+ usbip.enable = true;
85+ useWindowsDriver = true;
86+ };
87+88+ system.stateVersion = "24.05"; # Do you like bunnies?
89+90+ nixpkgs.hostPlatform = "x86_64-linux";
91+ };
92+ }
93+ @end
94+95+ `"${modules.nixos-wsl.src}/modules"` is equivalent to importing `inputs.nixos-wsl.nixosModules.default`. But it will be fetched only if I use NixOS-WSL, and not on other hosts.
96+** Roll the credits
97+ Okay, that's about all I know and use Nvfetcher for, as always, Thanks goes to:
98+ - {https://github.com/berberman}[@berberman] - for creating and maintaining such a nice program;
99+ - {https://github.com/iynaix}[@iynaix] - for information that Nvfetcher exists;
100+ - {https://git.gay/sunworms}[@sunworms] - for sharing a way to parse json file directly;
101+ - *You* - for reading to the end, have a nice day and reproducible builds.
···1+@document.meta
2+title: Hjem
3+description: link your home and feel superiour
4+authors: [
5+ ladas552
6+]
7+categories: [
8+ Home
9+ linker
10+ dotfiles
11+]
12+created: 2026-02-08T21:09:52+05:00
13+updated: 2026-02-08T21:09:52+05:00
14+draft: true
15+layout: post
16+version: 1.1.1
17+@end
18+19+* Hjem
20+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
21+ labore et dolore magna aliqua. Lobortis scelerisque fermentum dui faucibus in ornare.
+5
content/posts/index.norg
···00000
···1+@document.meta
2+title: Posts
3+description: All posts on this site
4+layout: posts
5+@end
···1+# Norgowind
2+Norgolith <3 TailwindCSS.
3+4+## Installation
5+```bash
6+lith theme pull github:NTBBloodbath/norgowind
7+```
8+9+> [!IMPORTANT]
10+>
11+> Currently, Norgowind requires the latest Norgolith commit in the master branch in order to work.
12+13+## Usage
14+15+> [!TIP]
16+>
17+> As Norgowind has been written using the standalone TailwindCSS CLI, you might want to use it if
18+> you plan to modify the CSS of the theme by hand. See the [Tailwind Reloading](#tailwind-reloading) section.
19+20+### Configuration
21+Besides the default `norgolith.toml` configuration options, Norgowind theme also requires the following configuration fields to be present:
22+23+```toml
24+# Custom additional configuration options with example values
25+[extra]
26+license = "GPLv2" # Optional
27+favicon_path = "/assets/norgolith.svg" # Fallback to the default norgolith favicon
28+footer_author_link = "https://github.com/NTBBloodbath" # Optional
29+enable_mermaid = true # If you want to use Mermaid.js for diagrams and charts
30+31+# Link_name = "url"
32+# e.g.
33+# blog = "/posts"
34+# GitHub = "https://github.com/NTBBloodbath/norgolith"
35+[extra.nav]
36+37+# Link_name = "url"
38+# GitHub = "https://github.com/NTBBloodbath/norgolith"
39+[extra.footer]
40+```
41+42+### Templates
43+Norgowind provides the following templates:
44+```
45+templates
46+├── partials
47+│ ├── footer.html <- Footer content
48+│ └── nav.html <- Header navbar
49+├── base.html <- Main template which gets extended by any other template
50+├── categories.html <- Categories list
51+├── category.html <- Category posts list
52+├── default.html <- Default template for all content
53+├── home.html <- Homepage
54+├── post.html <- Blog post
55+└── posts.html <- Posts list
56+```
57+58+In order to use a certain template, use the `layout` metadata field in your content files, e.g. if
59+you are writing a blog post:
60+```norg
61+layout: post
62+```
63+64+> [!TIP]
65+>
66+> Remember that Norgolith expects your blog posts to reside in the `content/posts` directory.
67+68+### Additional styling
69+Norgowind adds certain additional styling classes for blockquotes (add them to your blockquotes
70+using `+html.class` weak carryover tags):
71+- `tip` (green)
72+- `note` (blue)
73+- `important` (violet)
74+- `warning` (yellow)
75+- `error` (red)
76+77+
78+79+### Additional metadata fields
80+Norgowind also accepts and uses the following opt-in content metadata:
81+82+- `truncate`: configures the truncate characters length in the recent post cards.
83+- `truncate_char`: configures the truncate character, do not define it to use the default ellipsis. Leave it empty to disable the truncate character.
84+85+### Tailwind Reloading
86+By default, Tailwind's configuration in Norgowind will see content files, along with user and theme
87+templates. Each new class added to content using a weak carryover tag `+html.class` will
88+automatically be added to the styling file.
89+90+It is highly recommended to have the TailwindCSS CLI installed and run the following command during
91+development:
92+```sh
93+tailwindcss -i theme/assets/css/tailwind.css -o theme/assets/css/styles.min.css --watch
94+```
95+96+## License
97+Norgowind is licensed under MIT license.