# How twist.nix Integrates With Home Manager: A Complete Guide

> Learn how twist.nix integrates with Home Manager to declaratively manage your Emacs installations. Discover how it generates wrapper scripts, config files, and systemd services via programs emacs-twist. Explore the complete gui...

- Repository: [Emacs Twist/twist.nix](https://github.com/emacs-twist/twist.nix)
- Tags: how-to-guide
- Published: 2026-03-01

---

**twist.nix provides a dedicated Home Manager module that declaratively manages Emacs installations by generating wrapper scripts, configuration files, and systemd services through the `programs.emacs-twist` option set.**

The `emacs-twist/twist.nix` repository offers a modern, Nix-native package manager for Emacs. By integrating with Home Manager, twist.nix allows users to manage their entire Emacs environment— from the binary wrapper to init file generation—within their existing `home.nix` configuration without manual symlink management or shell script wrappers.

## Home Manager Module Architecture

The integration centers on `modules/home-manager.nix`, which defines a Home Manager module exposing the `programs.emacs-twist` option tree. This module bridges twist.nix’s package building capabilities with Home Manager’s declarative user environment management.

When enabled, the module performs several distinct operations: it builds the Emacs derivation with twist’s package manager support, generates a custom wrapper script that forces the correct init directory, and wires these into the user’s Home Manager profile through `home.packages` and `home.file` declarations.

## Configuring twist.nix in Home Manager

To activate the integration, set `programs.emacs-twist.enable = true` in your Home Manager configuration. The module exposes extensive options starting at line 58 of `modules/home-manager.nix`, including:

- `name`: The wrapper binary name (defaults to `emacs`)
- `directory`: The init directory path relative to `$HOME`
- `config`: The twist configuration attrset containing `emacs` (the built derivation) and `initFiles`
- `createInitFile`: Boolean to auto-generate `init.el` from concatenated source files
- `serviceIntegration.enable`: Boolean to register a systemd user service

## Key Integration Features

### Wrapper Script Generation

The module generates a critical wrapper script using `runCommandLocal` (lines 25-38 of `modules/home-manager.nix`). This wrapper invokes the twist-built Emacs binary while explicitly setting `--init-directory` to the user’s configured directory (defaulting to `~/.config/emacs`).

This approach ensures that Emacs always loads the correct configuration regardless of how it is launched, solving the common problem of Emacs loading the wrong init files when installed via Nix.

### Configuration File Management

Through `home.file` declarations (lines 70-91), the module optionally manages three critical configuration artifacts:

1. **`init.el`**: Concatenated from `cfg.config.initFiles` when `createInitFile` is true (lines 70-77)
2. **`early-init.el`**: Copied directly when `earlyInitFile` is specified (lines 78-82)
3. **Manifest JSON**: A hot-reload manifest written when `createManifestFile` is true, enabling dynamic package reloading without rebuilding Emacs (lines 84-91)

### Desktop Integration

The module provides desktop environment integration through `desktopItem` (lines 45-55). When the host platform is not macOS, it generates a `.desktop` file using `makeDesktopItem`, allowing Emacs to appear in application launchers and file manager "Open With" dialogs.

The desktop entry points to the generated wrapper script, ensuring that GUI launches use the correct Nix-managed Emacs binary and configuration directory.

### Systemd Service Registration

For Linux systems using systemd, the module can register a user service (lines 94-98). When `serviceIntegration.enable` is true, it configures `services.emacs` to use the twist wrapper as the service executable, enabling `systemctl --user start emacs` to launch the correctly configured Emacs daemon.

## Practical Configuration Example

The following `home.nix` demonstrates a complete twist.nix integration with Home Manager:

```nix
{ pkgs, ... }:

{
  programs.emacs-twist = {
    enable = true;
    
    # Custom wrapper name

    name = "my-emacs";
    
    # Init directory location

    directory = ".config/my-emacs";
    
    # Generate init.el from these files

    createInitFile = true;
    config = {
      initFiles = [
        ./init.el
        ./extra-config.el
      ];
      # The actual Emacs package built by twist.nix

      emacs = pkgs.emacs-twist;
    };
    
    # Desktop integration

    desktopItem.desktopName = "My Emacs";
    desktopItem.mimeTypes = [ "text/plain" "inode/directory" ];
    
    # Systemd service

    serviceIntegration.enable = true;
    
    # Enable emacsclient

    emacsclient.enable = true;
  };
}

```

This configuration produces:
- A `my-emacs` binary in `~/.local/bin` (the wrapper script)
- Concatenated configuration at `~/.config/my-emacs/init.el`
- A desktop entry for application launchers
- A systemd user service for daemon management

## Summary

- twist.nix integrates with Home Manager through `modules/home-manager.nix`, exposing the `programs.emacs-twist` option set.
- The module generates a wrapper script that ensures Emacs uses the correct init directory, solving configuration discovery issues.
- It manages `init.el`, `early-init.el`, and manifest files through `home.file` declarations for fully declarative configuration.
- Desktop integration and systemd service registration are available for Linux systems, while macOS support excludes desktop items.
- All functionality is activated by setting `programs.emacs-twist.enable = true` and configuring the appropriate options in `home.nix`.

## Frequently Asked Questions

### How do I enable twist.nix in my Home Manager configuration?

Set `programs.emacs-twist.enable = true` in your `home.nix` and provide the required `config` attribute set containing at minimum the `emacs` package (built via twist.nix) and optionally your `initFiles`. The module handles all wrapper generation and file placement automatically.

### Where does twist.nix place the Emacs configuration files?

By default, the module places configuration files in `~/.config/emacs` (or the path specified in `directory`). When `createInitFile` is enabled, it concatenates your specified `initFiles` into `init.el` at that location. It can also place `early-init.el` and a JSON manifest file for hot-reloading when those options are enabled.

### Can I use twist.nix with macOS and Linux?

Yes, the twist.nix Home Manager module supports both macOS and Linux. On Linux, it can generate desktop entries and systemd user services. On macOS, desktop item generation is automatically disabled, but the wrapper script and configuration file management function identically.

### How does the wrapper script work?

The wrapper script, generated via `runCommandLocal` in `modules/home-manager.nix`, invokes the twist-built Emacs binary while explicitly passing `--init-directory` to force Emacs to load configuration from the user-specified directory. This ensures consistent behavior regardless of how Emacs is launched (terminal, desktop file, or systemd service).