gimp-palette
v1.0.1
Published
GIMP Palette (gpl) parsing and conversion tools
Maintainers
Readme
gimp-palette
Parse, generate, and convert
.gpl(GIMP Palette) files — and export them straight into Tailwind CSS v4 themes.
What is this?
A dependency-free TypeScript library for working with the GIMP Palette (.gpl) format:
- Parse and generate full
.gplfiles (header, name, columns, comments, and colors). - Convert colors between RGB, HEX, HSL, and OKLCH.
- Generate Tailwind CSS v4
@themeblocks from a palette, ready to paste into your CSS, plus helpers for class names (bg-*,text-*,border-*,ring-*) and CSS variables.
Built for pixel-art / design-system workflows where you define a palette in GIMP (or export one from Aseprite as .gpl) and want it available as design tokens in your web project.
Installation
npm install gimp-palette
# or
pnpm add gimp-palette
# or
bun add gimp-paletteCLI
Convert GPL palettes to Tailwind CSS themes
npm install -g gimp-palette
gimp-palette /path/to/my/palette.gpl ./theme.cssQuick start
1. Parse a .gpl file
import { parse } from "gimp-palette";
const gplContent = `GIMP Palette
Name: Retro 8
Columns: 4
#
# Base test palette
#
255 0 0 Red
0 255 0 Green
0 0 255 Blue
`;
const palette = parse(gplContent);
console.log(palette);
// {
// name: "Retro 8",
// columns: 4,
// comments: "Base test palette",
// colors: [
// { r: 255, g: 0, b: 0, name: "Red" },
// { r: 0, g: 255, b: 0, name: "Green" },
// { r: 0, g: 0, b: 255, name: "Blue" },
// ]
// }Color lines with no name, or duplicate names, are resolved automatically (Color 1, Color 2, Red 2, ...). If you'd rather skip invalid color lines instead of throwing, use the omitInvalidColorDescriptions option:
parse(gplContent, { omitInvalidColorDescriptions: true });2. Generate a .gpl from data
import { stringify } from "gimp-palette";
const gpl = stringify({
name: "Retro 8",
columns: 4,
colors: [
{ r: 255, g: 0, b: 0, name: "Red" },
{ r: 0, g: 255, b: 0, name: "Green" },
],
});3. Convert individual colors
import { formatColor } from "gimp-palette";
const red = { r: 255, g: 0, b: 0, name: "Red" };
formatColor(red, "hex"); // "#FF0000"
formatColor(red, "rgb"); // "rgb(255, 0, 0)"
formatColor(red, "hsl"); // "hsl(0, 100%, 50%)"
formatColor(red, "oklch"); // "oklch(62.796% 0.2582 29.234)"You can also get structured conversions without formatting to a string:
import { toHex, toHsl, toOklch } from "gimp-palette/color";
toHex(red); // "#FF0000"
toHsl(red); // { h: 0, s: 100, l: 50 }
toOklch(red); // { l: 0.628, c: 0.258, h: 29.23 }4. Export the palette as a Tailwind CSS v4 theme
import { parse, toTailwindTheme } from "gimp-palette";
const palette = parse(gplContent);
const theme = toTailwindTheme(
palette,
{ namespaced: true },
);
console.log(theme);Output:
@theme {
--color-retro_8-red: oklch(62.796% 0.2582 29.234);
--color-retro_8-green: oklch(86.644% 0.2948 142.495);
--color-retro_8-blue: oklch(45.201% 0.3134 264.052);
}Plus helpers for using those tokens directly in markup or JS/TS:
toTailwindBg(red, { namespace: "retro_8" }); // "bg-retro_8-red"
toTailwindText(red); // "text-red"
toTailwindBorder(red); // "border-red"
toTailwindRing(red); // "ring-red"
toTailwindVariable(red, { namespace: "retro_8" }); // "var(--color-retro_8-red)"
toTailwindDefinition(red, { format: "hex" }); // "--color-red: #FF0000;"API
color
| Function | Description | | | |
| ------------------------------| -------------------------------------------------------------------------------------------------------------------------------------------| ---------| ---------| ------------|
| parse(value, resolveName?) | Parses a .gpl r g b name line. Throws InvalidColorStringError or InvalidRGBSequenceError if the format or RGB values are invalid. | | | |
| stringify(color) | Converts a GIMPPaletteColor back to its .gpl text line. | | | |
| toHex(color) | Returns the color as #RRGGBB. | | | |
| toHsl(color) | Returns { h, s, l } (0-360 / 0-100 / 0-100). | | | |
| toOklch(color) | Returns { l, c, h } in OKLCH space. | | | |
| format(color, format) | Formats the color as a string in the given ColorFormat ('hex' \ | 'rgb' \ | 'hsl' \ | 'oklch'). |
palette
| Function | Description |
| --- | --- |
| parse(content, opts?) | Parses the full contents of a .gpl file into a GIMPPalette object. Throws InvalidGPLStringError if the GIMP Palette header is missing. |
| stringify(palette) | Serializes a GIMPPalette back into .gpl format. |
tailwind
| Function | Description |
| --- | --- |
| toTheme(palette, opts?) | Generates an @theme { ... } (or @theme inline { ... }) block with all of the palette's color variables. |
| toDefinition(color, opts?) | Generates a single --color-name: value; line. |
| toBackgroundClassName(color, opts?) | bg-{name} |
| toTextClassName(color, opts?) | text-{name} |
| toBorderClassName(color, opts?) | border-{name} |
| toRingClassName(color, opts?) | ring-{name} |
| toVariable(color, opts?) | var(--color-{name}) |
Common options:
format?: 'oklch' \| 'hex' \| 'rgb' \| 'hsl'— value format for the color (defaults tooklch).namespace?: string/namespaced?: boolean— prefixes each variable with the palette name (e.g.retro_8-red), useful for avoiding collisions between palettes.inline?: boolean(toThemeonly) — generates@theme inline { ... }instead of@theme { ... }.
Types
type GIMPPaletteColor = { r: number; g: number; b: number; name: string };
type HSLColor = { h: number; s: number; l: number };
type OklchColor = { l: number; c: number; h: number };
type ColorFormat = 'oklch' | 'hex' | 'rgb' | 'hsl';
type GIMPPalette = {
name: string;
comments?: string;
columns?: number;
colors: GIMPPaletteColor[];
};Errors
InvalidColorStringError— the line doesn't match ther g b [name]pattern.InvalidRGBSequenceError— a RGB channel is out of the0-255range.InvalidGPLStringError— the file doesn't start with theGIMP Paletteheader.
Why OKLCH
The OKLCH conversion uses the standard sRGB → Linear → LMS → Oklab → OKLCH matrices, which lets you generate Tailwind v4 themes in a perceptually uniform color space (better than HSL for producing consistent tone/saturation scales). For achromatic colors (grays, white, black), hue (h) is normalized to 0 when chroma is negligible, avoiding unstable hue values from numerical noise.
Development
bun install
bun test
bun run buildLicense
MIT
