npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gimp-palette

v1.0.1

Published

GIMP Palette (gpl) parsing and conversion tools

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 .gpl files (header, name, columns, comments, and colors).
  • Convert colors between RGB, HEX, HSL, and OKLCH.
  • Generate Tailwind CSS v4 @theme blocks 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-palette

CLI

Convert GPL palettes to Tailwind CSS themes

npm install -g gimp-palette

gimp-palette /path/to/my/palette.gpl ./theme.css

Quick 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 to oklch).
  • namespace?: string / namespaced?: boolean — prefixes each variable with the palette name (e.g. retro_8-red), useful for avoiding collisions between palettes.
  • inline?: boolean (toTheme only) — 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 the r g b [name] pattern.
  • InvalidRGBSequenceError — a RGB channel is out of the 0-255 range.
  • InvalidGPLStringError — the file doesn't start with the GIMP Palette header.

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 build

License

MIT