Skip to content

Themes

Beyond the Home Manager module, NixKraken provides complementary packages for GitKraken themes.

These reside under the themes directory and are exposed as Flake outputs inside the packages.gitkraken-themes output.

For end-user usage within NixKraken and the list of available themes, see the theming guide.

Build

The main entry point for building themes is themes/default.nix. It defines a derivation that does two things:

  • bundle all theme sets as part of the derivation build
  • expose all theme sets as attributes of its passthru attribute

All theme sets

sh
# Build all theme sets using new Nix commands
$ nix build '.#gitkraken-themes'
sh
# ...or classic Nix commands
$ nix-build ./themes

The result directory will bundle all theme sets and their respective theme files in subdirectories named after the theme set, as shown below:

txt
result
├── catppuccin
│   ├── catppuccin-frappe.jsonc
│   ├── catppuccin-latte.jsonc
│   ├── catppuccin-macchiato.jsonc
│   ├── catppuccin-mocha.jsonc
│   └── VERSION
├── celestial-dark/
├── color-blind/
├── dracula/
├── matcha-dark-sea/
├── monochrome/
├── monokai/
├── night-owl/
├── nineteen-eighty-four/
├── nord/
├── oled-dream/
├── one-dark/
├── poimandres/
├── solarized/
├── the-matrix/
├── tokyo-night/
└── umbraco-dark/

18 directories, 41 files

INFO

This output is an example of the result directory built at the time of writing, actual content may change if themes are added/removed.

Specific theme set

sh
# Build Catppuccin theme set using new Nix commands
$ nix build '.#gitkraken-themes.catppuccin'
sh
# ...or classic Nix commands
$ nix-build ./themes -A catppuccin
txt
result
├── catppuccin-frappe.jsonc
├── catppuccin-latte.jsonc
├── catppuccin-macchiato.jsonc
└── catppuccin-mocha.jsonc

1 directory, 4 files

Directory Structure

Here is an overview of the themes directory structure:

txt
themes
├── sets
│   ├── catppuccin
│   │   └── package.nix
│   ├── celestial-dark
│   │   ├── celestial-dark.jsonc
│   │   └── package.nix
│   ├── color-blind/
│   ├── dracula/
│   └── ...
└── default.nix

All theme sets live in themes/sets under directories named after the set. The set directory is the attribute used for theme selection in the entry point.

Each set must define a package.nix file holding the derivation code, and may optionally include additional files needed for building the derivation.

Internals

Each theme is a Nix function that returns a derivation. Theme derivations must:

  1. Install JSONC files to the derivation output ($out)

  2. Expose variant filenames via passthru attribute

    • define a passthru attribute that maps the logical variant to the exact JSONC filename that GitKraken expects in ui.theme
    • for single-variant themes, set passthru.default to the filename

There are two common patterns, depending on whether the theme has a single variant or multiple variants.

Single Variant

For single variant themes, the derivation is straightforward:

nix
{
  stdenvNoCC,
  lib,
  fetchFromGitHub,
}:

let
  themePath = "tokyo-night-dark.jsonc";
in
stdenvNoCC.mkDerivation rec {
  name = "gitkraken-theme-tokyo-night";
  version = "1.4.0";

  src = fetchFromGitHub {
    owner = "jonbunator";
    repo = "gitkraken-custom-themes";
    rev = "v${version}";
    hash = "sha256-RCwitJ6HeFYJNsrc2lsVqAe1urfsi1RcxBYXXni6Fv0=";
  };

  installPhase = ''
    runHook preInstall
    mkdir -p $out
    cp Themes/TokyoNight/${themePath} $out
    runHook postInstall
  '';

  passthru.default = themePath;

  meta = {
    description = "Tokyo Night theme for GitKraken";
    homepage = "https://github.com/jonbunator/gitkraken-custom-themes/tree/v${version}/Themes/TokyoNight";
    license = lib.licenses.mit;
    maintainers = [ lib.maintainers.nicolas-goudry ];
  };
}

Multiple Variants

Multi-variant themes typically accept an optional withVariants argument, validate it against supported variants, and output multiple JSONC files accordingly.

Example (Catppuccin):

nix
{
  stdenvNoCC,
  lib,
  fetchFromGitHub,
  withVariants ? null,
}:

let
  defaultVariants = {
    frappe = "catppuccin-frappe.jsonc";
    latte = "catppuccin-latte.jsonc";
    macchiato = "catppuccin-macchiato.jsonc";
    mocha = "catppuccin-mocha.jsonc";
  };
  variantNames = lib.attrNames defaultVariants;
  variants = if withVariants == null then variantNames else withVariants;
in

assert lib.assertMsg (lib.isList variants) "withVariants must be a list";
assert lib.assertMsg (lib.length variants > 0) "withVariants cannot be empty";
assert lib.assertMsg (lib.all (variant: lib.elem variant variantNames)
  variants
) "withVariants uses invalid variants (valid variants: ${lib.concatStringsSep ", " variantNames})";

stdenvNoCC.mkDerivation rec {
  name = "gitkraken-theme-catppuccin";
  version = "1.1.0";

  src = fetchFromGitHub {
    owner = "catppuccin";
    repo = "gitkraken";
    rev = version;
    hash = "sha256-df4m2WUotT2yFPyJKEq46Eix/2C/N05q8aFrVQeH1sA=";
  };

  installPhase = lib.concatLines (
    lib.flatten [
      ''
        runHook preInstall
        mkdir -p $out
      ''
      (lib.map (variant: "cp themes/${defaultVariants.${variant}} $out") variants)
      "runHook postInstall"
    ]
  );

  passthru = lib.listToAttrs (
    lib.map (variant: lib.nameValuePair variant defaultVariants.${variant}) variants
  );

  meta = with lib; {
    description = "Soothing pastel theme for GitKraken";
    homepage = "https://github.com/catppuccin/gitkraken";
    license = licenses.mit;
    maintainers = [ maintainers.nicolas-goudry ];
  };
}

Maintenance

Add New Themes

The simplest approach is to copy an existing theme with a similar variant pattern (single vs multiple) and adapt it.

WARNING

GitKraken theme filenames must be unique across installed themes. If two themes install the same filename, they will overwrite each other.

Recommended checklist:

Choose a base (single or multiple variants) theme as template
Update name, version, src and meta
Update themePath (single variant themes only)
Update defaultVariants list (multiple variants themes only)
Ensure the JSONC files are copied from the correct source location to $out
Build the themes to validate your theme

Updating Themes

When a theme releases a new version:

  • bump the version attribute
  • update the src fetcher hash (e.g., for fetchFromGitHub)
    • easiest path: set hash = "" per the manual
    • build once (expected to fail), copy the reported hash into the derivation
  • verify file locations in the source repository
    • if paths changed, update the derivation's installPhase accordingly
  • verify file names in the source repository
    • if names changed, update the derivation's accordingly (themePath or defaultVariants)
  • rebuild and verify the passthru still matches the installed filenames
  • commit, push, open PR

Released under the MIT License