Watch
2
0
Fork
You've already forked feel-co--hjem
0
mirror of github.com/feel-co/hjem
  • Nix 64.6%
  • Rust 34.3%
  • CUE 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
éclairevoyant cef02450f2
Some checks failed
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, finix-basic) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, finix-xdg) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-basic) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-linker) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-no-users-linker) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-special-args) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-standalone) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-systemd-reload) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-xdg) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-22.04-arm, aarch64-linux, nixos-xdg-linker) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, finix-basic) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, finix-xdg) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-basic) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-linker) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-no-users-linker) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-special-args) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-standalone) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-systemd-reload) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-xdg) (push) Has been cancelled
Run VM tests / vm-tests (ubuntu-latest, x86_64-linux, nixos-xdg-linker) (push) Has been cancelled
Merge pull request #192 from feel-co/bump
bump
2026-09-22 12:55:53 +00:00
.github .github: drop unused platforms from PR template 2026-09-22 08:33:47 -04:00
cli build(deps): bump the rust-dependencies group in /cli with 2 updates 2026-09-21 01:45:21 +00:00
docs docs: update ndg CLI invocations; generate manpages 2026-07-31 21:43:00 +03:00
internal docs: update ndg CLI invocations; generate manpages 2026-07-31 21:43:00 +03:00
manifest manifest: v3 2026-02-15 21:21:29 -05:00
modules treewide: get Hjem CLI from config.cli.package 2026-08-05 07:51:25 +03:00
npins npins: bump 2026-09-22 08:32:12 -04:00
tests tests/finix: fix 2026-09-12 13:14:32 -04:00
.envrc flake: unflakeify devshell, formatter 2025-10-20 22:25:29 -04:00
.gitignore flake: add direnv, devshell 2025-06-13 22:09:17 -04:00
CONTRIBUTING.md docs: clarify wording in contrib guide; add scope examples 2025-10-18 09:32:35 -04:00
default.nix treewide: drop smfh from checks and remove all references to pkgs.smfh 2026-07-27 13:08:45 +03:00
flake.lock flake.lock: Update 2026-09-22 08:31:02 -04:00
flake.nix flake: use zstd tarballs for nixpkgs, as xz tarballs will be deprecated 2026-09-12 12:58:14 -04:00
lib.nix lib: ensure generators are only defined once 2026-06-01 15:31:51 -04:00
LICENSE meta: relicense 2025-02-18 17:46:13 +03:00
README.md treewide: drop smfh from checks and remove all references to pkgs.smfh 2026-07-27 13:08:45 +03:00

Hjem [ˈjɛmˀ]

A streamlined way to manage your $HOME with Nix.


Synopsis
Features | Interface
Future Plans

What is this?

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

We have learned from the mistakes made in the ecosystem.

  1. Powerful $HOME management functionality and potential
  2. Small and simple codebase with minimal abstraction
  3. Robust, safe and manifest based file handling with smfh
  4. Multi-user by design, works with any number of users
  5. Designed for ease of extensibility and integration

No compromises, only comfort.

How to use

Refer to our documentation at https://hjem.feel-co.org.

Standalone CLI

Hjem ships a standalone CLI, hjem, for non-NixOS and mixed setups.

The standalone entrypoint evaluates a Hjem manifest and applies it directly to the current user. switch and build accept exactly one manifest source:

  1. --manifest for a pre-generated manifest
  2. --config for a hjem.nix file
  3. --flake for a flake output

Examples:

# Evaluate a local hjem.nix and apply it.
$ hjem standalone switch --config ./hjem.nix

# Evaluate a flake with the default attr:
# hjemConfigurations."<USER>".manifest.
$ hjem standalone switch --flake .

# Evaluate a custom flake attribute explicitly.
$ hjem standalone switch \
  --flake . \
  --flake-attr 'hjemConfigurations."alice@laptop".manifest'

hjem.nix may evaluate to either a manifest directly or to an attribute set with a manifest attribute:

{
  version = 3;
  files = [
    {
      type = "symlink";
      source = ./dotfiles/example;
      target = "/home/alice/.config/example";
    }
  ];
}

Other standalone lifecycle commands:

# Build-only: evaluate and validate the manifest without applying it.
$ hjem standalone build --config ./hjem.nix

# List stored generations.
$ hjem standalone generations

# Roll back to the previous generation.
$ hjem standalone rollback

# Roll back to a specific generation id.
$ hjem standalone rollback --generation generation-1780000000-123456789

# Remove old generations by timestamp, while preserving the current generation.
$ hjem standalone expire-generations '-30 days'

# Keep only the newest N generations, while preserving the current generation.
$ hjem standalone expire-generations --keep-last 10

# Remove explicit generation ids. The current generation cannot be removed.
$ hjem standalone remove-generations generation-1780000000-123456789

Standalone state lives in $XDG_STATE_HOME/hjem/standalone, or ~/.local/state/hjem/standalone when XDG_STATE_HOME is unset. Use --state-dir on standalone commands to override that location.

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 = {
    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.alice or hjem.users.jane represent a user managed via users.users in NixOS. If a user does not exist, then Hjem will refuse to manage their $HOME by filtering non-existent users in file creation.

Module Interface

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

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.

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

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 .#hjem nix-build -A packages.hjem
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

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

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. You can set the hjem.linker option to use a custom linker if desired.

Attributions / Prior Art

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

This project is made available under Mozilla Public License (MPL) version 2.0. See LICENSE for more details on the exact conditions. An online copy is provided here.


  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. ↩︎