A colour palette generator: press space for a new set, lock the ones you like, and export the result in the formats design and code tools expect.
Build me a colour palette tool that replaces Coolors: generate, lock, adjust, check for contrast, and export into the formats my design and code tools want. STACK - Node 20+ with Fastify for the saved palettes, SQLite through better-sqlite3 - The generator itself is client-side vanilla JS — it must work instantly and offline - Colour maths with culori, or written by hand; no heavyweight dependency for what is a page of formulas - Caddy in front THE COLOUR MATHS, WHICH IS THE WHOLE TOOL - Work in OKLCH internally, not HSL. HSL's lightness is not lightness: a yellow and a blue at the same HSL lightness differ by a factor of three in how bright they look, which is why HSL-based generators produce palettes that fall apart the moment they are used - Convert to sRGB for display and clamp into gamut deliberately — reduce chroma, keep hue and lightness, and say in the interface when a colour was clipped - Support P3 output for browsers that have it, with an sRGB fallback in the same rule - Every formula in one module with tests against known values GENERATING - Space bar for a new palette, locks preserved. That is the interaction the product is famous for and it must be instant - Schemes, each generated properly in OKLCH: monochromatic, analogous, complementary, split complementary, triadic, tetradic, and a mode that simply spreads hue evenly with controlled lightness steps - Lightness ramps: from any base colour, a 50-to-950 scale with even perceptual steps, which is what a real interface needs and what most generators do not give you - Constrain the generation: a hue range, a chroma ceiling, a minimum contrast between adjacent swatches - Extract a palette from an uploaded image by clustering in OKLab, not by counting RGB values ADJUSTING - Click a swatch to open lightness, chroma and hue sliders, and see the hex, RGB, HSL, OKLCH and CSS colour name update together - Drag to reorder, lock, delete, insert - Undo and redo, with the whole history kept for the session - Keyboard for everything: space to generate, a number to lock, arrows to move CHECKING, WHICH IS WHY A PALETTE IS TRUSTWORTHY - A contrast matrix: every colour against every other, with the ratio and whether it passes AA and AAA for normal text, large text and non-text - The matrix is the default view, not a tab. A palette that has never been measured is decoration - Colour-blindness simulation for protanopia, deuteranopia and tritanopia, applied to the palette and to a sample interface - A live preview of a real interface — a card, a button, a chart, a table — painted in the palette, because swatches in a row lie SAVING AND SHARING - A palette is saved to a permanent URL, and the colours are in the URL itself so nothing is lost if the server goes away - Optional accounts by magic link, purely to list your own palettes - A generated preview image per palette for sharing, drawn server-side EXPORT - CSS custom properties, SCSS, Tailwind config, JSON, Swift, Android XML, GIMP and Adobe swatch files, SVG and PNG - Names generated from the ramp position, not from a colour-naming API - Copy each format with one button, and download all of them as a zip OPERATIONS - .env: DATABASE_PATH, BASE_URL, SESSION_SECRET - Migrations on boot, each once - The generator page is static and cached hard; only saving touches the server - Backup and restore scripts - Health endpoint WHAT MATTERS MOST OKLCH and the contrast matrix. Build the colour module with its tests first, then the space-bar loop. A generator that works in HSL will produce palettes that look plausible in a row of swatches and fail the moment somebody puts text on one — which is the only thing that matters. Give me the repository, migrations, .env.example, and a README with deploy steps behind Caddy and a note on the colour space choice.
What you lose
- A browsable library of palettes other people made, which is where most of the value is
- Contrast checking and colour-blindness simulation alongside the palette
- Exports into every design tool format
If you would rather not build
- Any OKLCH picker in a browser
- Open Color, a ready-made palette that already works
What it costs
read from their page 15 Aug 2026
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $3/mo | — | 15 Aug 2026 |
Their pricing page is where these came from. Seeing a different price? Tell us.
The escape hatch
open source · no votes, no paid placement
chroma.js
$0Scales, interpolation and contrast checks in a small library.
gka/chroma.jsfree · open source
Why this verdict
our own opinion · changed only by a person
91/100
Verdict yes at 91. Generating colour is easy; generating colour that passes contrast is the useful part, and it is arithmetic.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about Coolors
answered from the record above
Is Coolors free?
No — the plan we track is $3 a month. Pro at around $3/month billed annually.
Can you replace Coolors by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 91 out of 100, build time one session. Read what you lose before you decide.
How much does Coolors cost?
$3 a month on Pro — $36 a year. Recorded 10 Aug 2026.
What do you lose by replacing Coolors?
A browsable library of palettes other people made, which is where most of the value is; Contrast checking and colour-blindness simulation alongside the palette; Exports into every design tool format. If any of those carry weight for you, keep paying.
Is there an open-source alternative to Coolors?
Yes: culori, chroma.js. The prompt on this page is for when you want it your way instead.
Related entries
same category first, most replaced first
Every week, something stops being worth paying for.
New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.
free forever · no tracking pixel · stored here, never passed to anyone

