Release 26.11
This is the current unstable branch and the information in this section is therefore not final.
Highlights
This release has the following notable changes:
-
fzf shell integrations now source packaged scripts instead of running fzf to generate them. Custom programs.fzf.package values must include the integration scripts under
share/fzffor the enabled shells. Wrappers must preserve that directory alongside the executable, or use the default package, which already includes these files. -
The programs.uv module can now install uv-managed Python versions and tools through the new
programs.uv.python.versions,programs.uv.python.default, andprograms.uv.tool.packagesoptions. Unpinned entries track the latest release on each activation while pinned ones stay put, andprograms.uv.python.prune/programs.uv.tool.prunemake the managed set fully declarative by removing versions and tools that are no longer listed. -
On Darwin, Home Manager launchd agents now support launchd.agents.name.domain to choose either the user’s GUI or background launchd domain. Agents use the GUI domain by default. Set the domain to
userfor agents that should run without an active graphical login session. -
The services.voxtype.enable daemon now starts as part of
graphical-session.targetinstead ofdefault.target. Starting after the compositor owns its GPU render node lets Vulkan-accelerated whisper builds detect their device. Previously, a daemon that started before the render node existed fell back to CPU and never recovered until it was restarted manually. -
XSuspender now uses services.xsuspender.settings for freeform INI configuration. Move
services.xsuspender.defaultstoservices.xsuspender.settings.Defaultandservices.xsuspender.rulestoservices.xsuspender.settings.<name>. Use snake_case keys such assuspend_delayinstead ofsuspendDelay.Deprecated aliases warn and preserve old defaults, including legacy function reads, in legacy sections and
Default. These defaults have option-default priority, so ordinary assignments override them. Settings-only sections inherit fromDefaultat runtime, then use native defaults. To preserve old behavior, setsuspend_delayto 5 andonly_on_batterytofalse, rather than 10 andtrue.Without legacy options, empty settings leave the configuration file unmanaged. If you configured both
services.xsuspender.defaultsandservices.xsuspender.rules.Default, consolidate them underservices.xsuspender.settings.Default. They now merge instead of the rule replacing the entire defaults section. -
Notmuch now uses programs.notmuch.settings for native INI configuration. Deprecated options warn and map to
settings, for examplesearch.excludeTagstosettings.search.exclude_tags. Home Manager no longer writes values notmuch already defaults to (new.tags,new.ignore,maildir.synchronize_flags);new.ignoreorder may differ.programs.notmuch.extraConfigno longer overwrites other definitions. Definitions follow module priorities: forced values win, lists concatenate, and ordinary scalar or string/list collisions fail. Use a list forextraConfig.new.ignorewhen mbsync, lieer, or mujmap contributes patterns.lib.mkForceonextraConfigreplaces definitions in named sections. Section-levellib.mkDefaultloses to sections Home Manager or sync modules define:database,new,search, anduser. Null settings are omitted. -
TWMN now uses services.twmn.settings for freeform INI configuration. Legacy options emit migration warnings. Move native options and
extraConfigvalues intosettings, resolving duplicate definitions. Enabling the service without configuration no longer creates a config file. Settings-only configurations use TWMN’s native defaults; see the option documentation for compatibility limits and preserving previous defaults. -
Move
programs.openstackclient.cloudstoprograms.openstackclient.cloudsSettings.clouds, and moveprograms.openstackclient.publicCloudstoprograms.openstackclient.cloudsPublicSettings.public-clouds. The old options remain as deprecated aliases and emit warnings. -
Astroid now uses programs.astroid.settings for JSON configuration. Move
programs.astroid.extraConfigintosettings; replaceexternalEditor = "command"withsettings.editor.cmd = "command"andsettings.editor.external_editor = "true". Both old options warn; per-accountastroid.extraConfigis unchanged. Home Manager no longer writes a full default configuration; Astroid’s built-in defaults match it excepteditor.markdown_processor, nowcmark. Setsettings.editor.markdown_processor = "marked"to keepmarked. Without astroid accounts or settings, no config file is written.externalEditormerges at ordinary priority: differing ordinary editor keys conflict;lib.mkForcewins. Priorities onextraConfigsections apply as a unit.lib.mkForceon such a section drops its generated keys;lib.mkDefaultloses for sections Home Manager defines. Prefer per-key priorities. Replacing a generated section with a non-object value requireslib.mkForce. -
Grobi now uses services.grobi.settings for its complete JSON configuration. Move
services.grobi.executeAftertoservices.grobi.settings.execute_afterandservices.grobi.rulestoservices.grobi.settings.rules. The deprecated aliases preserve list order and definition priorities. The generated JSON is now pretty-printed. -
Borgmatic backups now use programs.borgmatic.backups.name.settings for native YAML settings. Deprecated options warn with the backup name and move to their snake_case keys, such as
retention.keepDailytosettings.keep_daily. Repository strings become{ path = "..."; }, and each section’sextraConfigmoves directly intosettings.location.excludeHomeManagerSymlinksremains available.Legacy configurations without overlapping keys keep their generated YAML, except that null check frequencies are now omitted. Overlapping
extraConfigkeys no longer take the last section’s value. Distinct scalars at the same priority conflict and lists concatenate, so resolve overlaps insettings. Backups no longer need exactly one ofsourceDirectoriesandpatterns, which allows native patterns and database-only backups.repositoriesis still required. -
programs.github-copilot-cli.settings is now written to
settings.jsoninstead ofconfig.json, since Copilot CLI 1.0.35 and later keep user settings there and replace a linkedconfig.json. The old link is removed on activation if it still points to a Home Manager generation; a regular state file is left alone. If Copilot CLI already created a regularsettings.jsonfrom the oldconfig.json, remove it before switching or enable programs.github-copilot-cli.mutableSettings to merge into it. With nonempty immutable settings, byte-identical files become managed links; differing files use normal collision and backup handling. Trusted folders insettingsare no longer written, because Copilot CLI keeps them in its own state; declare them with programs.github-copilot-cli.trustedFolders instead. -
Vicinae now requires version 0.17.0 or later. Legacy JSON themes and the
vicinae.jsonconfiguration file are no longer supported. Replaceprograms.vicinae.useLayerShellwithprograms.vicinae.settings.launcher_window.layer_shell.enabled. -
Mise’s mutable configuration switch is now programs.mise.mutableSettings. The former
programs.mise.enableMutableConfigremains a deprecated alias. Defaults and configuration behavior are unchanged. -
Option aliases, value conversions, and other compatibility code that had warned for at least one stable release were removed. Unless noted otherwise, configurations that still use the old options now fail to evaluate with an error that names the replacement. Options inside submodules, namely the lieer account options, the i3 and Sway
config.focus.forceWrappingoptions, and i3’sconfig.startup.*.workspace, fail as unknown options instead. Update them as follows:-
Core:
- The
home-managercommand no longer looks for configurations in$XDG_CONFIG_HOME/nixpkgsor~/.nixpkgs. Move them to$XDG_CONFIG_HOME/home-manager, or pass their path explicitly. - Setting
nixpkgs.configornixpkgs.overlayswhilehome-manager.useGlobalPkgsis enabled is now an error instead of a warning. - Set
qt.platformTheme.name = "gtk2"instead ofqt.useGtkTheme = true, andqt.platformTheme.nameinstead of a stringqt.platformTheme. Replace thekde6theme name withkde. Thegnometheme name no longer installs qgnomeplatform; useadwaita, or setqt.platformTheme.packageyourself. Neither name is checked any more, so old values are used as given without a warning. - Replace
i18n.inputMethod.enabledwithi18n.inputMethod.typeandi18n.inputMethod.enable = true.fcitx, removed in 23.05, is no longer an acceptedi18n.inputMethod.type; usefcitx5. - Replace
fonts.fontconfig.enableProfileFontswithfonts.fontconfig.enable,xdg.userDirs.publishSharewithxdg.userDirs.publicShare,specializationwithspecialisation,targets.genericLinux.extraXdgDataDirswithxdg.systemDirs.data,nixGLwithtargets.genericLinux.nixGL, andnix.gc.frequencywithnix.gc.dates. - The
lib.xdg.mimeAssociationsfunction was removed; usexdg.mimeApps.defaultApplicationPackages. launchd.agents.<name>.config.ProgramArgumentsvalues containing a literal&no longer warn. Home Manager escapes plist values itself, so write&instead.
- The
-
Services:
- In
xsession.windowManager.i3.configandwayland.windowManager.sway.config,fontsandbars.*.fontsmust be attribute sets. Replacefocus.forceWrapping = truewithfocus.wrapping = "force"for i3 or"yes"for Sway, and i3startup.*.workspacewithassigns. Replacewayland.windowManager.sway.systemdIntegrationwithwayland.windowManager.sway.systemd.enable. - Replace
services.kanshi.profilesandservices.kanshi.extraConfigwith the ordered listservices.kanshi.settings. Turn each named profile into a list entry withprofile.nameset to its former attribute name and its other options underprofile, and rewrite rawextraConfigas structured entries or put it in a file referenced by anincludeentry. Keep those entries after the profiles to preserve the previous order. - Replace
services.hyprsunset.transitionswith native profiles inservices.hyprsunset.settings.profile, such as[ { time = "21:00"; temperature = 5000; } ]. Rewrite each transition using the profile fieldstime,temperature,gamma, andidentity; Home Manager no longer creates per-transition systemd timers or runs theirhyprctlrequests. - Move the removed top-level
services.makooptions intoservices.mako.settings. Single-word names such asfontandwidthstay the same; camelCase names such asbackgroundColoranddefaultTimeoutbecomebackground-coloranddefault-timeout. - Move
services.redshift.brightness.dayandbrightness.nighttoservices.redshift.settings.redshift.brightness-dayandbrightness-night, and the Gammastep options toservices.gammastep.settings.general.brightness-dayandbrightness-night. - Replace
services.screen-locker.xssLockExtraOptions,xautolockExtraOptions, andenableDetectSleepwithservices.screen-locker.xss-lock.extraOptions,xautolock.extraOptions, andxautolock.detectSleep. - Replace
services.picom.opacityRulewithservices.picom.opacityRules,programs.wpaperdwithservices.wpaperd, andservices.gpg-agent.pinentryPackagewithservices.gpg-agent.pinentry.package.
- In
-
Git and diff tools:
- Move
programs.git.userName,userEmail, andaliasestoprograms.git.settings.user.name,settings.user.email, andsettings.alias,programs.git.extraConfigtoprograms.git.settings, andprograms.git.signing.gpgPathtoprograms.git.signing.signer. - Move the
programs.git.delta,diff-highlight,diff-so-fancy,difftastic,patdiff, andriffoptions toprograms.<tool>, with these exceptions. The diff-so-fancymarkEmptyLines,changeHunkIndicators,stripLeadingSymbols,useUnicodeRuler, andrulerWidthoptions, under eitherprograms.git.diff-so-fancyorprograms.diff-so-fancy, move toprograms.diff-so-fancy.settings.programs.git.difftastic.background,color,context, anddisplaymove toprograms.difftastic.options, andprograms.git.difftastic.enableAsDifftool = truebecomesprograms.difftastic.git.mode = "both". The oldenableoptions also turned on Git integration, so setprograms.<tool>.enableGitIntegration = true(for difftastic,programs.difftastic.git.enable = true) explicitly. - Replace
programs.gh.aliases,editor, andgitProtocolwithprograms.gh.settings.aliases,settings.editor, andsettings.git_protocol, andprograms.gh.enableGitCredentialHelperwithprograms.gh.gitCredentialHelper.enable.programs.gh.settingsno longer declaresaliases,editor, andgit_protocolwith defaults, so the generatedconfig.ymlomits them unless they are set, and gh uses its own defaults.
- Move
-
Shell and terminal programs:
- Replace
programs.zsh.initExtrawithprograms.zsh.initContent,initExtraFirstwithinitContentwrapped inlib.mkBefore, andinitExtraBeforeCompInitwithinitContentwrapped inlib.mkOrder 550. ReplaceenableAutosuggestions,enableSyntaxHighlighting, andzproofwithautosuggestion.enable,syntaxHighlighting.enable, andzprof. Relativeprograms.zsh.dotDirandprograms.zsh.history.pathvalues are now rejected; use absolute paths. - Replace
programs.bash.enableAutojumpwithprograms.autojump.enable,programs.direnv.enableNixDirenvIntegrationwithprograms.direnv.nix-direnv.enable, and the top-levelprograms.sshoptions, such asforwardAgentandcontrolPath, with the native directives underprograms.ssh.settings."*". - Combine
programs.go.goPathandextraGoPaths, in that order, intoprograms.go.env.GOPATH, and movegoBintoprograms.go.env.GOBINandgoPrivatetoprograms.go.env.GOPRIVATE. The old path options were relative to the home directory, so write absolute paths such as"${config.home.homeDirectory}/go". - Replace
programs.k9s.skin,hotkey, andpluginwithprograms.k9s.skins.skin,hotKeys, andplugins. Nestedalias,plugin, andk9s.viewskeys no longer warn; move their contents directly underprograms.k9s.aliases,plugins, andviews. - Replace
programs.kitty.themewithprograms.kitty.themeFile, using the theme’s file name without.confrather than its display name. For example,"Space Gray Eighties"becomes"SpaceGray_Eighties". - Replace
programs.mcfly.enableFuzzySearchwithprograms.mcfly.fuzzySearchFactor, using2fortrueand0forfalse, andprograms.less.keyswithprograms.less.config. - Use
programs.ezainstead ofprograms.exa, and"auto"ornullinstead of a Booleanprograms.eza.icons.programs.bat.themesandprograms.bat.syntaxesaccept only{ src; file; }attribute sets. Moveprograms.broot.modal,verbs, andskintoprograms.broot.settings. programs.keychain.agentsandprograms.keychain.inheritTypewere removed, because keychain 2.9.0 no longer supports them.
- Replace
-
Applications:
- For
programs.firefoxand the other Firefox-based browsers, addpkgs.gnome-browser-connectortonativeMessagingHostsinstead of settingenableGnomeExtensions, and dropvendorPath. Put bookmarks underbookmarks.settingswithbookmarks.force = true. - Firefox search engines are now referenced only by id, such as
ddgorgoogle. Display names such as"DuckDuckGo"insearch.default,search.privateDefault,search.order, and thesearch.engineskeys are no longer converted and are written unchanged. For custom search engines, useiconor numericiconMapObjkeys:iconURL,iconUpdateURL,hasPreferredIcon, and JSONiconMapObjkeys are no longer checked or converted and are written unchanged. Engines markedisAppProvided = truestill ignore icon fields. - Move
programs.vscode.enableUpdateCheck,enableExtensionUpdateCheck,userSettings,userTasks,userMcp,keybindings,extensions,languageSnippets, andglobalSnippetstoprograms.vscode.profiles.default, and replaceprograms.vscode.immutableExtensionsDirwith the inverseprograms.vscode.mutableExtensionsDir. programs.vim.pluginsaccepts only packages, andprograms.helix.languagesonly an attribute set, with the language list underlanguage.programs.neomutt.binds.*.mapandprograms.neomutt.macros.*.mapaccept only lists.- Replace
programs.msmtp.extraConfigwithprograms.msmtp.configContentwrapped inlib.mkBefore, andprograms.msmtp.extraAccountswithconfigContentwrapped inlib.mkAfter, so they stay before and after the generated accounts. - Under
accounts.email.accounts.<name>.lieer, replacedropNonExistingLabels,ignoreTagsRemote,ignoreTagsLocal,timeout, andreplaceSlashWithDotwithsettings.drop_non_existing_label,settings.ignore_remote_labels,settings.ignore_tags,settings.timeout, andsettings.replace_slash_with_dot. - Replace
programs.rtorrent.settingswithprograms.rtorrent.extraConfig.programs.thunderbird.darwinSetupWarningwas removed. - Replace
programs.anki.sync.passwordFilewithprograms.anki.profiles."User 1".sync.keyFile. programs.ashellnow requires ashell 0.5.0 or later and always writesashell/config.toml; it no longer generatesashell.ymlfor older versions, andprograms.ashell.settingsno longer accepts null. camelCase keys inprograms.ashell.settingsare no longer converted and are written as given, where ashell ignores them; use the upstream snake_case names.programs.hyprpanel.settings.theme.nameno longer warns; put theme contents directly underprograms.hyprpanel.settings.theme.
- For
-
State Version Changes
The state version in this release includes the changes below. These
changes are only active if the home.stateVersion option is set to
“26.11” or later.
-
programs.nushell.loadSessionVariables defaults to
truefromhome.stateVersion = "26.11". Nushell loads the Home Manager session environment at startup and, when used as a NixOS or nix-darwin module, the system environment too. This makes Home Manager manageenv.nu; migrate independently managed contents to programs.nushell.envFile or programs.nushell.extraEnv, or disable the option. Earlier state versions retain the old behavior and emit an evaluation warning untilprograms.nushell.loadSessionVariablesis explicitly set. -
On Darwin, the default value of programs.firefox.configPath changes from
Library/Application Support/FirefoxtoLibrary/Application Support/org.nixos.firefoxwhenprograms.firefox.packageis notnull. ExplicitconfigPathvalues remain unchanged. Users with ahome.stateVersionearlier than"26.11"should setprograms.firefox.configPath = "Library/Application Support/org.nixos.firefox";explicitly. Before changingconfigPath, quit Firefox and move your data from~/Library/Application Support/Firefoxto~/Library/Application Support/org.nixos.firefox. -
From
home.stateVersion = "26.11", notmuch no longer defaultssearch.exclude_tagstodeleted;spam, and it setsdatabase.pathonly when an email account is enabled. Earlier versions keep both defaults. To retain them when upgrading, setprograms.notmuch.settings.search.exclude_tags = [ "deleted" "spam" ];and, without email accounts, setprograms.notmuch.settings.database.pathto the mail directory, previouslyaccounts.email.maildirBasePath. -
The KDL options under
programs.zellijwill now correctly escape backslashes in string values. For example, the Nix string"\\"will now correctly generate the KDL string"\\". Previously, this would have generated"\", which is invalid KDL. The following options are affected:programs.zellij.settingsprograms.zellij.themesprograms.zellij.layouts
-
The KDL options under
programs.zellijwill now escape tabs in string values. For example, the Nix string"\t"(corresponding to a single tab) will now generate the KDL string"\t". Previously, this would have generated"<tab>"(where<tab>denotes a literal tab character). The following options are affected:programs.zellij.settingsprograms.zellij.themesprograms.zellij.layouts
-
The default value of programs.claude-code.configDir changes from
~/.claudeto${config.xdg.configHome}/claudewhen home.preferXdgDirectories is enabled. Existing Claude Code data in~/.claudeis not migrated automatically. Move it to the new directory before upgrading, or preserve the previous location by settingprograms.claude-code.configDir = "${config.home.homeDirectory}/.claude".