···11+@document.meta
22+title: Welcome to Flake-Ocean
33+description: This is a static site made using norgolith.
44+authors: [
55+ ladas552
66+]
77+categories: []
88+created: 2025-11-12
99+layout: home
1010+version: 1.1.1
1111+@end
1212+1313+* Nix
1414+ Hi, this is Ladas552 speaking
1515+1616+ You are reading beta version of docs for my NixOS config, It will explain how it works and why it works!
1717+1818+ Not because it's complicated, but for people to learn and grow with me.
1919+2020+ Have fun reading some articles, hopefully more and better down bellow.
2121+2222+ Feel free to ask questions to improve them to plank scale limits.
2323+2424+ 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.
2525+2626+ 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.
2727+2828+ 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
···11+@document.meta
22+title: Flake Parts
33+description: Deep dive into Nix Flakes
44+authors: ladas552
55+categories: [
66+ tutorial
77+ flakes
88+]
99+created: 2025-12-02
1010+layout: post
1111+draft: true
1212+version: 1.1.1
1313+@end
1414+1515+* Flake Parts
···11+@document.meta
22+title: Home Manager
33+description: Lazy house keeping service
44+authors: [
55+ ladas552
66+]
77+categories: [
88+ Home
99+ dotfiles
1010+]
1111+created: 2026-02-08T21:13:36+05:00
1212+updated: 2026-02-08T21:13:36+05:00
1313+draft: true
1414+layout: post
1515+version: 1.1.1
1616+@end
1717+1818+* Home Manager
1919+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
2020+ labore et dolore magna aliqua. Lobortis scelerisque fermentum dui faucibus in ornare.
+558
content/posts/Impermanence.norg
···11+@document.meta
22+title: Impermanence on NixOS with ZFS and tmpfs
33+description: Guide for my impermanence setup
44+authors: [
55+ ladas552
66+]
77+categories: [
88+ Impermanence
99+ ZFS
1010+ Guide
1111+]
1212+created: 2026-01-02
1313+draft: false
1414+layout: post
1515+version: 1.1.1
1616+@end
1717+1818+** What is Impermanence
1919+ ___
2020+ 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.
2121+2222+ For example you can install full KDE Plasma session, run it, and if you get bored. Just disable it and no KDE junk left.
2323+2424+ *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
2525+2626+ Also when I refer to `/root`, it's actually the whole `/`, not just root user directory.
2727+*** Why did you set it up
2828+ ___
2929+ 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.
3030+3131+ But there are some benefits to it:
3232+ - I only backup important files, no cache, no states, only files and media;
3333+ - I always know what's on my system because it's declared in the config;
3434+ - 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;
3535+*** What's the meaning of writing this page?
3636+ ___
3737+ 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.
3838+3939+ 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.
4040+4141+*** What is your current setup?
4242+ ___
4343+4444+ 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.
4545+4646+ 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.
4747+4848+ Template structure of ZFS datasets that will be essential:
4949+5050+ - `/cache` is for rust targets, everything in `~/.cache`, .local states, etc.
5151+5252+ - `/persist` is for Media, browser profiles, Projects, etc. This is the only datasets that get's backed up by `sanoid`.
5353+5454+ - `/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.
5555+5656+ - `/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.
5757+5858+ tmpfs is erased on reboot, so `/` and everything below it, including `/home` is gone, unless put into `/cache` or `/persist` datasets.
5959+ 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.
6060+6161+** What we need?
6262+*** A ZFS setup
6363+ 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.
6464+6565+ {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.
6666+ @code sh
6767+ sudo zpool create -f \
6868+ -o ashift=12 \
6969+ -o autotrim=on \
7070+ -O compression=zstd \
7171+ -O acltype=posixacl \
7272+ -O atime=off \
7373+ -O xattr=sa \
7474+ -O normalization=formD \
7575+ -O mountpoint=none \
7676+ zroot "/dev/sda2"
7777+7878+ sudo zfs create -o mountpoint=legacy zroot/root
7979+ sudo mount -t zfs zroot/root /mnt
8080+8181+ sudo mount --mkdir "$BOOTDISK" /mnt/boot
8282+ # All the stuff below will be explained later
8383+ sudo zfs create -o mountpoint=legacy zroot/nix
8484+ sudo mount --mkdir -t zfs zroot/nix /mnt/nix
8585+8686+ sudo zfs create -o mountpoint=legacy zroot/tmp
8787+ sudo mount --mkdir -t zfs zroot/tmp /mnt/tmp
8888+8989+ sudo zfs create -o mountpoint=legacy zroot/cache
9090+ sudo mount --mkdir -t zfs zroot/cache /mnt/cache
9191+9292+ sudo zfs create -o mountpoint=legacy zroot/persist
9393+ sudo zfs snapshot zroot/persist@blank
9494+ sudo mount --mkdir -t zfs zroot/persist /mnt/persist
9595+ # All the stuff above will be explained later
9696+ sudo nixos-install --no-root-password --flake "github:Ladas552/Nix-Is-Unbreakable#NixVM"
9797+ @end
9898+9999+*** Partitions
100100+ ___
101101+ A new way to manage your system. NixOS.
102102+103103+ Tho you probably already use NixOS if you are reading this, if you don't then get out while you can.
104104+105105+ On a more serious note, you need ZFS setup, with 2 particular datasets.
106106+ @code nix
107107+ fileSystems = {
108108+ "/nix" = {
109109+ device = "zroot/nix";
110110+ fsType = "zfs";
111111+ };
112112+ "/tmp" = {
113113+ device = "zroot/tmp";
114114+ fsType = "zfs";
115115+ };
116116+ };
117117+ @end
118118+119119+ If you don't have them, but have ZFS installed, just create them using commands
120120+ @code sh
121121+ sudo zfs create -o mountpoint=legacy zroot/tmp
122122+ sudo zfs create -o mountpoint=legacy zroot/nix
123123+ @end
124124+125125+ 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.
126126+127127+*** Impermanence module
128128+ ___
129129+ 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
130130+131131+ 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.
132132+133133+ 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.
134134+135135+ 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}.
136136+137137+ 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.
138138+139139+**** You forgot to tell installation instructions
140140+ ___
141141+ It's nix so here is just a snippet of code. Works for flakes.
142142+ @code nix
143143+ #flake.nix
144144+ {
145145+ inputs.impermanence.url = "github:nix-community/impermanence";
146146+ }
147147+ @end
148148+ And then just import the module, like:
149149+ @code nix
150150+ imports = [
151151+ inputs.impermanence.nixosModules.impermanence
152152+ ];
153153+ @end
154154+155155+ 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.
156156+157157+ 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.
158158+*** Immutable users
159159+ ___
160160+ As we delete everything in `/root`, it means passwords for users, and most importantly `root` user will be deleted.
161161+162162+ So just make them immutable. You can store the password file in sops, or just provide raw path from `/persist` directory.
163163+164164+ @code nix
165165+ {
166166+ # setup immutable users for impermanence
167167+168168+ # silence warning about setting multiple user password options
169169+ # https://github.com/NixOS/nixpkgs/pull/287506#issuecomment-1950958990
170170+ # Stolen from Iynaix https://github.com/iynaix/dotfiles/blob/4880969e7797451f4adc3475cf33f33cc3ceb86e/nixos/users.nix#L18-L24
171171+ options = {
172172+ warnings = lib.mkOption {
173173+ apply = lib.filter (
174174+ w: !(lib.hasInfix "If multiple of these password options are set at the same time" w)
175175+ );
176176+ };
177177+ };
178178+179179+ config = {
180180+ # disabling user mutability
181181+ users.mutableUsers = false;
182182+183183+ # defining regular user, ME!
184184+ users.users.ladas552 = {
185185+ isNormalUser = true;
186186+ description = "Ladas552";
187187+ extraGroups = [
188188+ "networkmanager"
189189+ "wheel"
190190+ ];
191191+ initialPassword = "pass";
192192+ # Use a path or your encryption method here
193193+ hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
194194+ };
195195+196196+ nix.settings.trusted-users = [ "ladas552" ];
197197+198198+ # Setting root user
199199+ users.users.root = {
200200+ initialPassword = "pass";
201201+ hashedPasswordFile = config.sops.secrets."mystuff/host_pwd".path;
202202+ };
203203+ };
204204+ }
205205+ @end
206206+207207+ Other features for immutable users:
208208+ - Can use `--no-root-password` flag in `nixos-install` command. Meaning you don't ever have to monitor it, it will install password automatically.
209209+ - 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.
210210+211211+ 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.
212212+213213+*** When do we start deleting stuff?
214214+ ___
215215+ Not so fast bakaru, we first need to save our stuff.
216216+217217+ So you need to create persisted directories
218218+ @code sh
219219+ sudo zfs create -o mountpoint=legacy zroot/persist
220220+ sudo zfs create -o mountpoint=legacy zroot/cache
221221+ @end
222222+223223+ And now we add them to be mounted on boot
224224+ @code nix
225225+ # persist mount
226226+ fileSystems."/persist" = {
227227+ device = "zroot/persist";
228228+ fsType = "zfs";
229229+ # so it's required to boot, and you won't reboot into empty desktop
230230+ neededForBoot = true;
231231+ };
232232+233233+ # cache are files that should be persisted, but not to snapshot
234234+ # e.g. npm, cargo cache etc, that could always be redownload
235235+ "/cache" = {
236236+ device = "zroot/cache";
237237+ fsType = "zfs";
238238+ neededForBoot = true;
239239+ };
240240+ @end
241241+242242+ I also recommend setting up backups with sanoid if you didn't already.
243243+244244+ @code nix
245245+ services.sanoid = {
246246+ enable = true;
247247+ # if you have sanoid options somewhere else, lib.mkForce
248248+ # will override anything, so you only have snapshots that matter
249249+ datasets = lib.mkForce {
250250+ "zroot/persist" = {
251251+ hourly = 50;
252252+ daily = 15;
253253+ weekly = 3;
254254+ monthly = 1;
255255+ };
256256+ };
257257+ };
258258+ @end
259259+260260+ Now we have basic datasets that will store out stuff, Impermanence can wait now, we need to assign bind mounts for directories and files!
261261+262262+ 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.
263263+264264+ 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.
265265+266266+ 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.
267267+268268+*** Okay, we have locations, let's move some files into them
269269+ ___
270270+ So, with Impermanence module, there are some options available. Simplest approach would be to use it directly
271271+272272+ @code nix
273273+ environment.persistence = {
274274+ # one of out datasets
275275+ "/persist" = {
276276+ # useful option
277277+ hideMounts = true;
278278+ directories = [
279279+ # absolute path to directories in string values
280280+ "/var/log"
281281+ "/var/lib/nixos"
282282+ "/etc/NetworkManager/"
283283+ ];
284284+ };
285285+ };
286286+ @end
287287+288288+ 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.
289289+290290+**** New options
291291+ ___
292292+ `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.
293293+294294+ 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.
295295+296296+ @code nix
297297+ {lib,...}:
298298+ {
299299+ options = {
300300+ # options to put directories in, persistence but shortened
301301+ # stolen from @iynaix
302302+ root = {
303303+ directories = lib.mkOption {
304304+ type = lib.types.listOf lib.types.str;
305305+ default = [ ];
306306+ description = "Directories to persist in root filesystem";
307307+ };
308308+ files = lib.mkOption {
309309+ type = lib.types.listOf lib.types.str;
310310+ default = [ ];
311311+ description = "Files to persist in root filesystem";
312312+ };
313313+ cache = {
314314+ directories = lib.mkOption {
315315+ type = lib.types.listOf lib.types.str;
316316+ default = [ ];
317317+ description = "Directories to persist, but not to snapshot";
318318+ };
319319+ files = lib.mkOption {
320320+ type = lib.types.listOf lib.types.str;
321321+ default = [ ];
322322+ description = "Files to persist, but not to snapshot";
323323+ };
324324+ };
325325+ };
326326+ home = {
327327+ directories = lib.mkOption {
328328+ type = lib.types.listOf lib.types.str;
329329+ default = [ ];
330330+ description = "Directories to persist in home directory";
331331+ };
332332+ files = lib.mkOption {
333333+ type = lib.types.listOf lib.types.str;
334334+ default = [ ];
335335+ description = "Files to persist in home directory";
336336+ };
337337+ cache = {
338338+ directories = lib.mkOption {
339339+ type = lib.types.listOf lib.types.str;
340340+ default = [ ];
341341+ description = "Directories to persist, but not to snapshot";
342342+ };
343343+ files = lib.mkOption {
344344+ type = lib.types.listOf lib.types.str;
345345+ default = [ ];
346346+ description = "Files to persist, but not to snapshot";
347347+ };
348348+ };
349349+ };
350350+ };
351351+ }
352352+ # Holy cow nix is indented to all suns
353353+ @end
354354+355355+ 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.
356356+357357+ `home` is just a simple way to separate directories in `/home/ladas552` from just `/`.
358358+359359+ 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!
360360+361361+ @code nix
362362+ { lib, ... }:
363363+ # link to snippet in my config
364364+ # https://github.com/Ladas552/Flake-Ocean/blob/85ee207aa2e5e0d2e44aad0a0818a533ceca72cf/modules/nixosModules/Impermanence/imp-options.nix
365365+ {
366366+ flake.modules =
367367+ let
368368+ # options to put directories in, persistence but shortened
369369+ # stolen from @iynaix
370370+371371+ root = {};
372372+ home = {};
373373+ # Same thing as above
374374+ in
375375+ {
376376+ nixos.options.options.custom.imp = { inherit root home; };
377377+ hjem.options.options.custom.imp = { inherit home; };
378378+ homeManager.options.options.custom.imp = { inherit home; };
379379+ };
380380+ }
381381+ @end
382382+383383+ 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.
384384+385385+ You probably didn't get any of that, but you don't need to tbh. My setup is My setup, do whatever you want.
386386+387387+**** Persist in action
388388+ ___
389389+ Now we can define some important directories and files to persist
390390+ @code nix
391391+ custom.imp = {
392392+ root = {
393393+ directories = [
394394+ "/etc/NetworkManager/"
395395+ "/var/lib/NetworkManager"
396396+ "/var/lib/iwd"
397397+ ];
398398+ };
399399+ home = {
400400+ directories = [
401401+ ".librewolf"
402402+ ];
403403+ cache = {
404404+ files = [ ".local/share/com.jeffser.Alpaca/alpaca.db" ];
405405+ directories = [
406406+ ".local/share/nvim"
407407+ ".local/state/nvim"
408408+ ".config/libreoffice"
409409+ ".cache/librewolf"
410410+ ".cache/keepassxc"
411411+ ".config/keepassxc"
412412+ ".cache/nix"
413413+ ".cache/nix-index"
414414+ ];
415415+ };
416416+ };
417417+ };
418418+ @end
419419+420420+ 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.
421421+422422+ @code nix
423423+ { lib, config, ... }:
424424+ let
425425+ cfg = config.custom.imp;
426426+ # config.custom.meta.user is just my placeholder for `username`
427427+ # just hard code the value, or replace it with your own solution to select a user
428428+ cfghm = config.home-manager.users."${config.custom.meta.user}".custom.imp;
429429+ cfghj = config.hjem.users."${config.custom.meta.user}".custom.imp;
430430+ in
431431+ {
432432+ environment.persistence = {
433433+ "/persist" = {
434434+ hideMounts = true;
435435+ # referencing files via our abstraction option
436436+ files = lib.unique cfg.root.files;
437437+ directories = lib.unique (
438438+ # here you can define directories normally
439439+ [
440440+ "/var/log"
441441+ "/var/lib/nixos"
442442+ ]
443443+ # and concatenate too!
444444+ ++ cfg.root.directories
445445+ );
446446+ # add persists to `/home/user` path
447447+ users."${config.custom.meta.user}" = {
448448+ files = lib.unique ([ ] ++ cfghm.home.files ++ cfghj.home.files);
449449+ directories = lib.unique (
450450+ [ ] ++ cfg.home.directories ++ cfghm.home.directories ++ cfghj.home.directories
451451+ );
452452+ };
453453+ };
454454+ # same as above
455455+ "/cache" = {
456456+ hideMounts = true;
457457+ files = lib.unique cfg.root.cache.files;
458458+ directories = lib.unique cfg.root.cache.directories;
459459+ users."${config.custom.meta.user}" = {
460460+ files = lib.unique (cfg.home.cache.files ++ cfghm.home.cache.files ++ cfghj.home.cache.files);
461461+ directories = lib.unique (
462462+ cfg.home.cache.directories ++ cfghm.home.cache.directories ++ cfghj.home.cache.directories
463463+ );
464464+ };
465465+ };
466466+ };
467467+ }
468468+ @end
469469+470470+ 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.
471471+472472+ 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.
473473+474474+ Now upon rebuild Impermanence module should add all the interesting directories to datasets and establish bind mounts.
475475+476476+ Wait, did we forget something? Uhhh...
477477+478478+*** DELETE ERASE REDUCTED
479479+ ___
480480+ @code nix
481481+ # replace the root mount with tmpfs
482482+ # wipes everything if you don't have proper persists, be warned
483483+ fileSystems."/" = lib.mkForce {
484484+ device = "tmpfs";
485485+ fsType = "tmpfs";
486486+ neededForBoot = true;
487487+ options = [
488488+ "defaults"
489489+ # whatever size feels comfortable, smaller is better
490490+ "size=1G"
491491+ "mode=755"
492492+ ];
493493+ };
494494+ @end
495495+496496+ This is all you need. So simple in comparison to the whole page above, right?
497497+498498+ The main reasons for that are:
499499+ - It's harder to keep what you have gained, but trivial to loose everything you ever had;
500500+ - 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.
501501+502502+ This should be all you need to start using tmpfs for impermanence on ZFS.
503503+504504+ There are some niceties I want to share tho, to make your life easier.
505505+506506+*** Some sprinkles to your epitome of agony
507507+**** Snippets
508508+ ___
509509+ Set this so you aren't lectured by `you know what you are doing` lecture from sudo every boot
510510+ @code nix
511511+ security.sudo.extraConfig = "Defaults lecture=never";
512512+ @end
513513+514514+ 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.
515515+ @code nix
516516+ sops.age.sshKeyPaths = [
517517+ "/persist/home/vimjoyer/.ssh/ssh-key"
518518+ ];
519519+ sops.age.keyFile = lib.mkDefault "/persist/home/vimoyer/.config/sops/age/keys.txt";
520520+ @end
521521+522522+**** Persist everything
523523+ ___
524524+ 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
525525+ @code nix
526526+ # persist steam
527527+ custom.imp.home = {
528528+ cache.directories = [
529529+ ".local/share/Steam"
530530+ ".cache/mesa_shader_cache"
531531+ ".cache/mesa_shader_cache_db"
532532+ ".cache/radv_builtin_shaders"
533533+ ];
534534+ };
535535+ @end
536536+537537+ 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.
538538+539539+ Some pretty extended persist list can be found in following configurations:
540540+ - {https://github.com/search?q=repo%3Aiynaix%2Fdotfiles+custom.persist&type=code}[Iynaix dotfiles];
541541+ - {https://github.com/saygo-png/nixos}[Saygo's config];
542542+ - {https://github.com/xarvex/dotfyls}[Xarvex dotfyls];
543543+544544+ 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.
545545+546546+**** Credits and suggestions
547547+ ___
548548+ 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!
549549+550550+ List of awesome people:
551551+ - *Iynaix*'s impermanence abstraction structure and ZFS setup
552552+ - *Vimjoyer*'s Impermanence video introducing basic concept to me
553553+ - *talyz* for making Impermanence module and extensive readme for the project
554554+ - *Graham* for {https://grahamc.com/blog/erase-your-darlings/}
555555+ - *Willbush* for {https://willbush.dev/blog/impermanent-nixos/}
556556+ - *Elis Hirwing* for {https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/}
557557+ - {https://github.com/fliplus}[Flipus] and *snohater* for providing feedback on readability of the thing.
558558+ - *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.
···11+@document.meta
22+title: Nvfetcher
33+description: Inputs outside of flakes
44+authors: [
55+ ladas552
66+]
77+categories: [
88+ inputs
99+ un-flake
1010+]
1111+created: 2026-02-08
1212+draft: false
1313+layout: post
1414+version: 1.1.1
1515+@end
1616+1717+** What is Nvfetcher?
1818+ 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`.
1919+** Why don't you just use flakes?
2020+ Even tho I love flakes, I can acknowledge that they have issues. Namely, in the context of inputs:
2121+ - 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`;
2222+ - 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;
2323+ - Inputs are hella slow. No, I am not benchmarking it, just feels like this.
2424+2525+ In this case, Nvfetcher comes in handy. Fetchers work only if you import the input.
2626+*** What about Npins?
2727+ I don't like using cli interface to generate fetches. Also It has problems with AppImages.
2828+** How to use Nvfetcher?
2929+ Go read the docs in the {https://github.com/berberman/nvfetcher}[project's repository].
3030+3131+ 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.
3232+3333+ For example, it works wonders for fetching neovim plugins.
3434+ @code nix
3535+ # nvfetcher pins
3636+ sources = pkgs.callPackage "${self}/_sources/generated.nix" { };
3737+ heirline-components = pkgs.vimUtils.buildVimPlugin {
3838+ name = "heirline-components.nvim";
3939+ doCheck = false;
4040+ src = sources.heirline-components.src;
4141+ };
4242+ @end
4343+4444+ 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.
4545+4646+ And here is a custom example of using the json file directly.
4747+4848+ @code nix
4949+ sourcesJson = builtins.fromJSON (builtins.readFile ./_sources/generated.json);
5050+5151+ modules = builtins.mapAttrs (
5252+ name: value:
5353+ let
5454+ src = fetchTarball {
5555+ url = "${value.src.url}/archive/${value.src.rev}.tar.gz";
5656+ sha256 = value.src.sha256;
5757+ };
5858+ in
5959+ value // { inherit src; }
6060+ ) sourcesJson;
6161+ @end
6262+6363+ 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.
6464+6565+ Demonstration of one of my hosts that is NixOS-WSL based.
6666+6767+ @code nix
6868+ { modules, ... }:
6969+ {
7070+ flake.modules.nixos.NixwsL =
7171+ { config, ... }:
7272+ {
7373+ imports = [
7474+ "${modules.nixos-wsl.src}/modules"
7575+ ];
7676+ networking.hostName = "NixwsL";
7777+ wsl = {
7878+ enable = true;
7979+ # if you are wondering what these config options are
8080+ # it will be explained in another article
8181+ defaultUser = "${config.custom.meta.user}";
8282+ startMenuLaunchers = true;
8383+ tarball.configPath = "${config.custom.meta.self}";
8484+ usbip.enable = true;
8585+ useWindowsDriver = true;
8686+ };
8787+8888+ system.stateVersion = "24.05"; # Do you like bunnies?
8989+9090+ nixpkgs.hostPlatform = "x86_64-linux";
9191+ };
9292+ }
9393+ @end
9494+9595+ `"${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.
9696+** Roll the credits
9797+ Okay, that's about all I know and use Nvfetcher for, as always, Thanks goes to:
9898+ - {https://github.com/berberman}[@berberman] - for creating and maintaining such a nice program;
9999+ - {https://github.com/iynaix}[@iynaix] - for information that Nvfetcher exists;
100100+ - {https://git.gay/sunworms}[@sunworms] - for sharing a way to parse json file directly;
101101+ - *You* - for reading to the end, have a nice day and reproducible builds.
···11+@document.meta
22+title: Hjem
33+description: link your home and feel superiour
44+authors: [
55+ ladas552
66+]
77+categories: [
88+ Home
99+ linker
1010+ dotfiles
1111+]
1212+created: 2026-02-08T21:09:52+05:00
1313+updated: 2026-02-08T21:09:52+05:00
1414+draft: true
1515+layout: post
1616+version: 1.1.1
1717+@end
1818+1919+* Hjem
2020+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
2121+ labore et dolore magna aliqua. Lobortis scelerisque fermentum dui faucibus in ornare.
+5
content/posts/index.norg
···11+@document.meta
22+title: Posts
33+description: All posts on this site
44+layout: posts
55+@end
···11+# Norgowind
22+Norgolith <3 TailwindCSS.
33+44+## Installation
55+```bash
66+lith theme pull github:NTBBloodbath/norgowind
77+```
88+99+> [!IMPORTANT]
1010+>
1111+> Currently, Norgowind requires the latest Norgolith commit in the master branch in order to work.
1212+1313+## Usage
1414+1515+> [!TIP]
1616+>
1717+> As Norgowind has been written using the standalone TailwindCSS CLI, you might want to use it if
1818+> you plan to modify the CSS of the theme by hand. See the [Tailwind Reloading](#tailwind-reloading) section.
1919+2020+### Configuration
2121+Besides the default `norgolith.toml` configuration options, Norgowind theme also requires the following configuration fields to be present:
2222+2323+```toml
2424+# Custom additional configuration options with example values
2525+[extra]
2626+license = "GPLv2" # Optional
2727+favicon_path = "/assets/norgolith.svg" # Fallback to the default norgolith favicon
2828+footer_author_link = "https://github.com/NTBBloodbath" # Optional
2929+enable_mermaid = true # If you want to use Mermaid.js for diagrams and charts
3030+3131+# Link_name = "url"
3232+# e.g.
3333+# blog = "/posts"
3434+# GitHub = "https://github.com/NTBBloodbath/norgolith"
3535+[extra.nav]
3636+3737+# Link_name = "url"
3838+# GitHub = "https://github.com/NTBBloodbath/norgolith"
3939+[extra.footer]
4040+```
4141+4242+### Templates
4343+Norgowind provides the following templates:
4444+```
4545+templates
4646+├── partials
4747+│ ├── footer.html <- Footer content
4848+│ └── nav.html <- Header navbar
4949+├── base.html <- Main template which gets extended by any other template
5050+├── categories.html <- Categories list
5151+├── category.html <- Category posts list
5252+├── default.html <- Default template for all content
5353+├── home.html <- Homepage
5454+├── post.html <- Blog post
5555+└── posts.html <- Posts list
5656+```
5757+5858+In order to use a certain template, use the `layout` metadata field in your content files, e.g. if
5959+you are writing a blog post:
6060+```norg
6161+layout: post
6262+```
6363+6464+> [!TIP]
6565+>
6666+> Remember that Norgolith expects your blog posts to reside in the `content/posts` directory.
6767+6868+### Additional styling
6969+Norgowind adds certain additional styling classes for blockquotes (add them to your blockquotes
7070+using `+html.class` weak carryover tags):
7171+- `tip` (green)
7272+- `note` (blue)
7373+- `important` (violet)
7474+- `warning` (yellow)
7575+- `error` (red)
7676+7777+
7878+7979+### Additional metadata fields
8080+Norgowind also accepts and uses the following opt-in content metadata:
8181+8282+- `truncate`: configures the truncate characters length in the recent post cards.
8383+- `truncate_char`: configures the truncate character, do not define it to use the default ellipsis. Leave it empty to disable the truncate character.
8484+8585+### Tailwind Reloading
8686+By default, Tailwind's configuration in Norgowind will see content files, along with user and theme
8787+templates. Each new class added to content using a weak carryover tag `+html.class` will
8888+automatically be added to the styling file.
8989+9090+It is highly recommended to have the TailwindCSS CLI installed and run the following command during
9191+development:
9292+```sh
9393+tailwindcss -i theme/assets/css/tailwind.css -o theme/assets/css/styles.min.css --watch
9494+```
9595+9696+## License
9797+Norgowind is licensed under MIT license.