• Theme protocol: the base of all themes.

    ThemeKit makes available, without any further coding:

    • a LightTheme (the default macOS theme)
    • a DarkTheme (the dark macOS theme, using NSAppearanceNameVibrantDark)
    • a SystemTheme (which dynamically resolve to either LightTheme or `DarkTheme depending on the macOS preference at System Preferences > General > Appearance)

    You can choose wheter or not to use these, and you can also implement your custom themes by:

    • implementing native Theme classes conforming to this protocol and NSObject
    • provide user themes (UserTheme) with .theme files

    Please check the provided project for sample implementations of both.

    See more



    public protocol Theme: NSObjectProtocol
  • A Theme class wrapping a user provided theme file (.theme).

    To enable user themes, set theme folder on ThemeManager.userThemesFolderURL.

    Notes about .theme files:

    • lines starting with # or // will be treated as comments, thus, ignored;
    • non-comment lines consists on simple variable/value assignments (eg, variable = value);
    • variable name can contain characters [a-zA-Z0-9_-.]+;
    • custom variables can be specified (eg, myBackgroundColor = ...);
    • theming properties match the class methods of ThemeColor, ThemeGradient and ThemeImage (eg, labelColor);
    • variables can be referenced by prefixing them with $ (eg, mainBorderColor = $commonBorderColor);
    • colors are defined using rgb(255, 255, 255) or rgba(255, 255, 255, 1.0) (case insensitive);
    • gradients are defined using linear-gradient(color1, color2) (where colors are defined as above; case insensitive);
    • pattern images are defined using pattern(named:xxxx) (named images) or pattern(file:../dddd/xxxx.yyy) (filesystem images);
    • images are defined using image(named:xxxx) (named images) or image(file:../dddd/xxxx.yyy) (filesystem images);
    • ThemeManager.themes property is automatically updated when there are changes on the user themes folder;
    • file changes are applied on-the-fly, if it corresponds to the currently applied theme.

    Example .theme file:

    // ************************* Theme Info ************************* //
    displayName = My Theme 1
    identifier = com.luckymarmot.ThemeKit.MyTheme1
    darkTheme = true
    // ********************* Colors & Gradients ********************* //
    # define color for `ThemeColor.brandColor`
    brandColor = $blue
    # define a new color for `NSColor.labelColor` (overriding)
    labelColor = rgb(11, 220, 111)
    # define gradient for `ThemeGradient.brandGradient`
    brandGradient = linear-gradient($, rgba(200, 140, 60, 1.0))
    // ********************* Images & Patterns ********************** //
    # define pattern image from named image "paper" for color `ThemeColor.contentBackgroundColor`
    contentBackgroundColor = pattern(named:paper)
    # define pattern image from filesystem (relative to user themes folder) for color `ThemeColor.bottomBackgroundColor`
    bottomBackgroundColor = pattern(file:../some/path/some-file.png)
    # use named image "apple"
    namedImage = image(named:apple)
    # use image from filesystem (relative to user themes folder)
    fileImage = image(file:../some/path/some-file.jpg)
    // *********************** Common Colors ************************ //
    blue = rgb(0, 170, 255) = rgb(160, 90, 45, .5)
    // ********************** Fallback Assets *********************** //
    fallbackForegroundColor = rgb(255, 10, 90, 1.0)
    fallbackBackgroundColor = rgb(255, 200, 190)
    fallbackGradient = linear-gradient($blue, rgba(200, 140, 60, 1.0))

    With the exception of system overrided named colors (e.g., labelColor), which defaults to the original system provided named color, unimplemented properties on theme file will default to -fallbackForegroundColor, -fallbackBackgroundColor, -fallbackGradient and -fallbackImage, for foreground color, background color, gradients and images, respectively.

    See more



    public class UserTheme: NSObject, Theme