Skip to content

NixOS

For NixOS users, a Nix package for Noctalia is available. You can also get the Git version, NixOS module and Home Manager module via flakes.

To install Noctalia, you need to add a flake input and install the package.

Add the required inputs to your flake configuration:

flake.nix
{
description = "NixOS configuration with Noctalia";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
noctalia = {
url = "github:noctalia-dev/noctalia/legacy-v4";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs@{ self, nixpkgs, ... }: {
nixosConfigurations.awesomebox = nixpkgs.lib.nixosSystem {
specialArgs = { inherit inputs; };
modules = [
# ... other modules
./noctalia.nix
];
};
};
}

With the flake installed, we can access Noctalia packages and modules in our configuration.

If you don’t use Noctalia’s NixOS or home-manager modules, you need to manually install the default Noctalia package from the new noctalia input:

noctalia.nix
{ pkgs, inputs, ... }:
{
# install package
environment.systemPackages = with pkgs; [
inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default
# ... maybe other stuff
];
}

Rebuild with sudo nixos-rebuild switch --flake ..


Pre-built binaries are available on Cachix, so you can skip compiling locally.

You can add the cache either to your flake, nixos configuration, or /etc/nix/nix.conf.

nixConfig = {
extra-substituters = [ "https://noctalia.cachix.org" ];
extra-trusted-public-keys = [ "noctalia.cachix.org-1:pCOR47nnMEo5thcxNDtzWpOxNFQsBRglJzxWPp3dkU4=" ];
};

If you have home manager installed, you can configure your Noctalia shell in Nix.

To configure Noctalia settings, you can use the Noctalia home manager module:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# import the home manager module
imports = [
inputs.noctalia.homeModules.default
];
# configure options
programs.noctalia-shell = {
enable = true;
settings = {
# configure noctalia here
bar = {
density = "compact";
position = "right";
showCapsule = false;
widgets = {
left = [
{
id = "ControlCenter";
useDistroLogo = true;
}
{
id = "Network";
}
{
id = "Bluetooth";
}
];
center = [
{
hideUnoccupied = false;
id = "Workspace";
labelMode = "none";
}
];
right = [
{
alwaysShowPercentage = false;
id = "Battery";
warningThreshold = 30;
}
{
formatHorizontal = "HH:mm";
formatVertical = "HH mm";
id = "Clock";
useMonospacedFont = true;
usePrimaryColor = true;
}
];
};
};
colorSchemes.predefinedScheme = "Monochrome";
general = {
avatarImage = "/home/drfoobar/.face";
radiusRatio = 0.2;
};
location = {
monthBeforeDay = true;
name = "Marseille, France";
};
};
# this may also be a string or a path to a JSON file.
};
};
}

We don’t have extensive documentation of Noctalia’s configuration options; however, you can see an up-to-date list of configuration defaults.

Additionally, since ~/.config/noctalia/settings.json is now a read-only symlink, you can get the latest (or GUI-modified) settings via: Open Settings Panel -> General -> Copy Settings or by running noctalia-shell ipc call state all | jq .settings, then use them to update your Nix config for a permanent change.

To configure Noctalia settings, you can use the Noctalia home manager module. Be sure to set every Material 3 color, including hover-state values, when overriding the defaults:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# import the home manager module
imports = [
inputs.noctalia.homeModules.default
];
# configure options
programs.noctalia-shell = {
enable = true;
colors = {
# you must set ALL of these
mError = "#dddddd";
mOnError = "#111111";
mOnPrimary = "#111111";
mOnSecondary = "#111111";
mOnSurface = "#828282";
mOnSurfaceVariant = "#5d5d5d";
mOnTertiary = "#111111";
mOnHover = "#ffffff";
mOutline = "#3c3c3c";
mPrimary = "#aaaaaa";
mSecondary = "#a7a7a7";
mShadow = "#000000";
mSurface = "#111111";
mHover = "#1f1f1f";
mSurfaceVariant = "#191919";
mTertiary = "#cccccc";
};
# this may also be a string or a path to a JSON file.
};
};
}

The user-templates option allows you to define custom templates. This is useful for theming other applications that are not supported by default.

It can be a string, a path, or an attribute set.

As a string:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# ...
programs.noctalia-shell = {
enable = true;
settings = {
templates = {
enableUserTemplates = true;
};
};
user-templates = ''
[config]
# General template settings
[templates.myapp]
input_path = "~/.config/noctalia/templates/myapp.css"
output_path = "~/.config/myapp/theme.css"
post_hook = "myapp --reload-theme"
'';
};
};
}

As a path:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# ...
programs.noctalia-shell = {
enable = true;
settings = {
templates = {
enableUserTemplates = true;
};
};
user-templates = ./path/to/user-templates.toml;
};
};
}

As an attribute set:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# ...
programs.noctalia-shell = {
enable = true;
settings = {
templates = {
enableUserTemplates = true;
};
};
user-templates = {
config = {
# General template settings
};
templates = {
myapp = {
input_path = "~/.config/noctalia/templates/myapp.css";
output_path = "~/.config/myapp/theme.css";
post_hook = "myapp --reload-theme";
};
};
};
};
};
}

You can configure plugins in a declarative way. If an enabled plugin isn’t installed in the plugin directory, Noctalia will automatically install it when starts up.

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# import the home manager module
imports = [
inputs.noctalia.homeModules.default
];
# configure options
programs.noctalia-shell = {
enable = true;
plugins = {
sources = [
{
enabled = true;
name = "Official Noctalia Plugins";
url = "https://github.com/noctalia-dev/noctalia-plugins";
}
];
states = {
catwalk = {
enabled = true;
sourceUrl = "https://github.com/noctalia-dev/noctalia-plugins";
};
};
version = 2;
};
# this may also be a string or a path to a JSON file.
pluginSettings = {
catwalk = {
minimumThreshold = 25;
hideBackground = true;
};
# this may also be a string or a path to a JSON file.
};
};
};
}

Wallpapers are configured in ~/.cache/noctalia/wallpapers.json. You can set them declaratively:

noctalia.nix
{ pkgs, inputs, ... }:
{
home-manager.users.drfoobar = {
# ... other config ...
home.file.".cache/noctalia/wallpapers.json" = {
text = builtins.toJSON {
defaultWallpaper = "/path/to/default/wallpaper.png";
wallpapers = {
"DP-1" = "/path/to/monitor/wallpaper.png";
};
};
};
};
}

Keybindings are configured in your compositor. You make IPC calls to Noctalia as explained in the keybinds section. The only difference is that you can call noctalia-shell instead of qs -c noctalia-shell.

To safely configure noctalia keybindings in the Niri flake, be sure to pass a list:

niri.nix
{ pkgs, inputs, ... }:
{
# ...
home-manager.users.drfoobar =
{ config, ... }:
{
# ...
programs.niri = {
settings = {
# ...
binds = with config.lib.niri.actions; {
"Mod+Space".action.spawn = [
"noctalia-shell" "ipc" "call" "launcher" "toggle" # ✅
];
"Mod+P".action.spawn =
"noctalia-shell ipc call sessionMenu toggle"; # ❌
};
};
};
}

It may be convenient to define a utility function to allow you to use simple strings:

niri.nix
{ pkgs, inputs, ... }:
let
noctalia = cmd: [
"noctalia-shell" "ipc" "call"
] ++ (pkgs.lib.splitString " " cmd);
in
{
# ...
home-manager.users.drfoobar =
{ config, lib, ... }:
{
# ...
programs = {
niri = {
# ...
settings = {
binds = with config.lib.niri.actions; {
# ...
"Mod+L".action.spawn = noctalia "lockScreen lock";
"XF86AudioLowerVolume".action.spawn = noctalia "volume decrease";
"XF86AudioRaiseVolume".action.spawn = noctalia "volume increase";
"XF86AudioMute".action.spawn = noctalia "volume muteOutput";
# etc
};
};
};
};
}

To run Noctalia using the flake, run:

Terminal window
noctalia-shell

With the Niri flake, you can then spawn Noctalia on startup like this:

niri.nix
{ pkgs, inputs, ... }:
{
# ...
home-manager.users.drfoobar = {
# ...
programs.niri = {
package = niri;
settings = {
# ...
spawn-at-startup = [
{
command = [
"noctalia-shell"
];
}
];
};
};
};
}

To add support for events in the calendar via evolution-data-server.

  1. Enable the evolution-data-server:
services.gnome.evolution-data-server.enable = true;
  1. Override the Noctalia package:
(pkgs.noctalia-shell.override { calendarSupport = true; })

or

(inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override { calendarSupport = true; })

There is no comprehensive documentation of all configuration options, but the default values are autogenerated and placed in a settings-default.json in the Noctalia repository. We retrieve a live Nixified version of these here for your convenience:

noctalia.nix
# Failed to fetch settings: 404 Not Found