Omarchy Theme Export

lib

Serializes an Omarchy palette back into colors.toml text, without touching the desktop.

bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/omarchy-theme-export

Dependencies

registry
yamz8/omarchy-shadcn-registry/omarchy-palette

Source

registry/lib/omarchy-theme-export.ts
import type { OmarchyTheme } from "@/lib/omarchy-palette"

type TomlLine = readonly [key: string, value: string | undefined]

/**
 * Serializes a theme back into Omarchy's `colors.toml` format, preserving the
 * upstream field names, order, and blank-line grouping. Optional fields absent
 * from a palette (`orange`, `brown`) are omitted rather than guessed.
 *
 * This only produces text. Writing it to `~/.config/omarchy/themes/<name>/`
 * and activating it with `omarchy theme set` is deliberately left to the user —
 * nothing here reads or mutates the desktop.
 */
export function toOmarchyColorsToml(theme: OmarchyTheme): string {
  const sections: readonly (readonly TomlLine[])[] = [
    [["mode", theme.mode]],
    [
      ["accent", theme.accent],
      ["selection", theme.selection],
      ["muted", theme.muted],
    ],
    [
      ["background", theme.background],
      ["dark_background", theme.darkBackground],
      ["darker_background", theme.darkerBackground],
      ["lighter_background", theme.lighterBackground],
    ],
    [
      ["foreground", theme.foreground],
      ["dark_foreground", theme.darkForeground],
      ["light_foreground", theme.lightForeground],
      ["bright_foreground", theme.brightForeground],
    ],
    [
      ["red", theme.red],
      ["yellow", theme.yellow],
      ["orange", theme.orange],
      ["green", theme.green],
      ["cyan", theme.cyan],
      ["blue", theme.blue],
      ["magenta", theme.magenta],
      ["brown", theme.brown],
    ],
    [
      ["bright_red", theme.brightRed],
      ["bright_yellow", theme.brightYellow],
      ["bright_green", theme.brightGreen],
      ["bright_cyan", theme.brightCyan],
      ["bright_blue", theme.brightBlue],
      ["bright_magenta", theme.brightMagenta],
    ],
  ]

  const blocks = sections
    .map((section) =>
      section
        .filter((line): line is readonly [string, string] => Boolean(line[1]))
        .map(([key, value]) => `${key} = "${value}"`)
        .join("\n")
    )
    .filter(Boolean)

  return `${blocks.join("\n\n")}\n`
}