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
passthruattribute
All theme sets
# Build all theme sets using new Nix commands
$ nix build '.#gitkraken-themes'# ...or classic Nix commands
$ nix-build ./themesThe result directory will bundle all theme sets and their respective theme files in subdirectories named after the theme set, as shown below:
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 filesINFO
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
# Build Catppuccin theme set using new Nix commands
$ nix build '.#gitkraken-themes.catppuccin'# ...or classic Nix commands
$ nix-build ./themes -A catppuccinresult
├── catppuccin-frappe.jsonc
├── catppuccin-latte.jsonc
├── catppuccin-macchiato.jsonc
└── catppuccin-mocha.jsonc
1 directory, 4 filesDirectory Structure
Here is an overview of the themes directory structure:
themes
├── sets
│ ├── catppuccin
│ │ └── package.nix
│ ├── celestial-dark
│ │ ├── celestial-dark.jsonc
│ │ └── package.nix
│ ├── color-blind/
│ ├── dracula/
│ └── ...
└── default.nixAll 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:
Install JSONC files to the derivation output (
$out)Expose variant filenames via
passthruattribute- define a
passthruattribute that maps the logical variant to the exact JSONC filename that GitKraken expects inui.theme - for single-variant themes, set
passthru.defaultto the filename
- define a
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:
{
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):
{
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
- easiest path: set
- verify file locations in the source repository
- if paths changed, update the derivation's
installPhaseaccordingly
- if paths changed, update the derivation's
- verify file names in the source repository
- if names changed, update the derivation's accordingly (
themePathordefaultVariants)
- if names changed, update the derivation's accordingly (
- rebuild and verify the passthru still matches the installed filenames
- commit, push, open PR