feel-co/hjem
{ "createdAt": "2024-12-13T17:28:48Z", "defaultBranch": "main", "description": "Streamlined, elegant $HOME management with Nix", "fullName": "feel-co/hjem", "homepage": "https://hjem.feel-co.org/", "language": "Nix", "name": "hjem", "pushedAt": "2025-11-24T06:17:34Z", "stargazersCount": 232, "topics": [], "updatedAt": "2025-11-24T22:24:00Z", "url": "https://github.com/feel-co/hjem"}
Hjem [ˈjɛmˀ]
A streamlined way to manage your $HOME with Nix.
Synopsis
Features | Interface
Future Plans
What is this?
Section titled “What is this?”[systemd-tmpfiles] !: https://www.freedesktop.org/software/systemd/man/latest/systemd-tmpfiles-setup.service.html [smfh] !: https://github.com/feel-co/smfh
Hjem (“home” in Danish) is a module system that implements a simple and
streamlined way to manage files in your $HOME, such as but not limited to
files in your ~/.config. Hjem aims to approach as an alternative,
easy-to-grasp utility for managing your $HOME purely and safely.
Features
Section titled “Features”We have learned from the mistakes made in the ecosystem.
- Powerful
$HOMEmanagement functionality and potential - Small and simple codebase with minimal abstraction
- Robust, safe and manifest based file handling with [smfh]
- Multi-user by design, works with any number of users
- Designed for ease of extensibility and integration
No compromises, only comfort.
Implementation
Section titled “Implementation”Hjem exposes a streamlined interface with multi-tenant capabilities, which you may use to manage individual users’ homes by leveraging the module system.
{ inputs, lib, pkgs, ... }:{ /* other NixOS configuration here... */
hjem = { # use our custom file handler linker = inputs.hjem.packages.${pkgs.stdenv.hostPlatform.system}.smfh;
users = { alice = { enable = true;
files = { # Write a text file in `/home/alice/.foo` # with the contents bar ".foo".text = "bar";
# Alternatively, create the file source using a writer. # This can be used to generate config files with various # formats expected by different programs. ".bar".source = pkgs.writeText "file-foo" "file contents";
# You can also use generators to transform Nix values ".baz" = { # Works with `pkgs.formats` too! generator = lib.generators.toJSON { }; value = { some = "contents"; }; }; };
# this will write into `/home/alice/.config/test/bar.json` xdg.config.files."test/bar.json" = { generator = lib.generators.toJSON { }; value = { foo = 1; bar = "Hello world!"; baz = false; }; # overwrite existing unmanaged file, if present clobber = true; }; }; }; };}[!NOTE] Each attribute under
hjem.users, e.g.,hjem.users.aliceorhjem.users.janerepresent a user managed viausers.usersin NixOS. If a user does not exist, then Hjem will refuse to manage their$HOMEby filtering non-existent users in file creation.
Module Interface
Section titled “Module Interface”[already does!] !: https://github.com/snugnug/hjem-rum
The interface for the hjem module is conceptually very similar to prior art
(e.g., Home Manager), but it does not act as a collection of modules like Home
Manager. Instead, we implement minimal features, and leave
application-specific abstractions to the user to do as they see fit.
This, of course, does not mean that a module collection cannot exist.
In fact, one [already does!]
Below is a live implementation of the module.
$ nix eval .#nixosConfigurations.test.config.hjem.users.alice.files.'".foo"' --json | jq{ "clobber": false, "enable": true, "executable": false, "generator": null, "relativeTo": "/home/alice", "source": "/nix/store/22yfhzhk0w5mgaq6c943vimsg6qlr1sh-foo", "target": "/home/alice/.foo", "text": "bar", "value": null}Linker Implementation
Section titled “Linker Implementation”Hjem relies on our home-baked tool [smfh], an atomic and reliable file creation tool designed by [Gerg-l]. We utilize smfh and Systemd services [^1] to correctly link files into place.
[^1] !: Which is preferable to hacky activation scripts that may or may not break.
Systemd services allow for ordered dependency management across all
services, and easy monitoring of Hjem-related services from the central
systemctl interface.
Environment Management
Section titled “Environment Management”Hjem does not manage user environments as one might expect, but it provides
a convenient environment.sessionVariables option that you can use to store
your variables. This script will be used to store your environment variables in
a POSIX-compliant script generated by Hjem, which you can source in your shell
configurations.
Usage without flakes
Section titled “Usage without flakes”We support usage without flakes. Specifically, you can use the following shell commands:
| With flakes | Without flakes |
|---|---|
nix flake check | nix-build -A checks |
nix develop | nix-shell -A shell |
nix build .#smfh | nix-build -A packages.smfh |
nix fmt | nix run -f . formatter |
You can also import the root of the repo and get all of the same attributes as the flake (without system).
Things to do
Section titled “Things to do”Hjem is mostly feature-complete, in the sense that it is a clean
implementation of home.files in Home Manager: it was never a goal to dive into
abstracting files into modules.
Alternative or/and configurable file linking mechanisms
Section titled “Alternative or/and configurable file linking mechanisms”[Gerg-l] !: https://github.com/gerg-l
Hjem previously utilized systemd-tmpfiles to ensure files are linked in place. This served us well for the short duration that we relied on them, but we have ultimately decided to go with our in-house file linker developed by [Gerg-l]. The new linker is, of course, infinitely more powerful and while we are not looking back, we understand that some users might be interested in alternative linking mechanisms that they can customize as they prefer.
[!TIP] Setting
hjem.linkertonullwill use [systemd-tmpfiles] as the linker backend. You may give this option a package you’ve created to use it as your linker, but it must be fully compatible with the interface [smfh] currently supports.
Alternatively, similar to how NixOS handles external bootloaders, we may consider a rebuild “hook” for allowing alternative linking methods where the module system exposes the files configuration to a package user provides.
Attributions / Prior Art
Section titled “Attributions / Prior Art”[Nixpkgs] !: https://github.com/nixOS/nixpkgs [Home Manager] !: https://github.com/nix-community/home-manager [Hjem Rum] !: https://github.com/snugnug/hjem-rum [@Lunarnovaa] !: https://github.com/lunarnovaa [@nezia1] !: https://github.com/nezia1
Special thanks to [Nixpkgs] and [Home Manager]. The interface of the
hjem.users module is inspired by Home Manager’s home.file and Nixpkgs’
users.users modules. What is now Hjem started as an experimental module
addition to Nixpkgs’ users.users. Hjem would not be possible without any of
those projects, thank you!
A project worthy of note is [Hjem Rum], by [@Lunarnovaa] and [@nezia1], which establishes a Home Manager-like module system for users less comfortable with manually linking files in place. If you wish to utilize the power of Hjem, but want an easier interface, we encourage you to take a look at Hjem Rum.
Last but not least, our sincerest thanks to everyone who has used, contributed to or just talked about Hjem in public spaces. Thank you for the support!
License
Section titled “License”This project is made available under Mozilla Public License (MPL) version 2.0. See [LICENSE]!(LICENSE) for more details on the exact conditions. An online copy is provided here.