Contributing to Juna

Juna is built on the principle of explicit authorship. We value technical depth, performance, and clean abstractions. If you want to contribute, keep it simple and respect the domain boundaries of the system.


Core Rules

  1. No Global Side Effects: A module should only affect its specific application. Do not touch home.sessionVariables or xdg.configFile unless absolutely necessary for that domain's realization.
  2. Lazy Realization: Assets (fonts, icon packs, theme packages) should only be added to the Nix store if the user explicitly enables that module.
  3. Pigment Flexibility: Use junaAllThemes to allow users to override the global theme for specific applications. Never hardcode hex values.

Adding a New Theme

Themes live in ./themes/. Every theme must be an attribute set containing at minimum:

  • colors: A base16-compatible set of pigments.
  • message: A brief string displayed on activation (optional).
  • wallpapers: A derivation or path to assets.

Adding a New Module (Domain)

Modules should follow this structure. Note how the module allows a per-application theme override that defaults to the global Juna theme.

{
  lib,
  config,
  junaAllThemes,
  ...
}: let
  cfg = config.juna.domain.app;
in {
  options.juna.domain.app = {
    enable = lib.mkEnableOption "Juna integration for [App]";

    theme = lib.mkOption {
      type = lib.types.str;
      default = config.juna.theme or "";
      example = "nord";
      description = "The active pigment profile Juna should deploy for this module.";
    };
  };

  config = lib.mkIf (config.juna.enable && cfg.enable && cfg.theme != "") {
    # 1. Access the specific theme from the global set
    # let 
    #   palette = junaAllThemes."${cfg.theme}".colors;
    # in { ... }

    # 2. Map pigments to application-specific config logic
    # programs.app.settings = {
    #   bg = palette.base00;
    #   fg = palette.base05;
    # };
  };
}


Pull Request Requirements

  • Logic Check: Ensure the module only triggers if config.juna.enable, and cfg.enable are all true.
  • Performance: Avoid deep recursive merges where flat attribute sets suffice.
  • Documentation: Each option must provide default value, an example value, and a clear description value.