Over the weekend, I built Colors on the Curve, a parametric color palette builder, with native Figma export support. You can use the webapp, the tui or the npm package.
Motivation
Designing a scalable, versatile, yet coherent color system for a design system has always been challenging for me. The traditional workflows are usually one of the following:
1. Build Your Color System From Scratch
You have to figure out how many hues you are going to use, how many shades each hue should have, and how those shades should look on an individual basis, without any kind of systemic, deterministic method.
The problem with this approach is that it takes a long time to get your colors to look coherent, especially in terms of how saturation changes across the shades of one hue compared to another. And a lot of it is guesswork. Even though color is a very solved piece of the puzzle in terms of how its parameters work and how each parameter affects the result, it is bizarre to me how manual the workflow of making a good, coherent color system still is. I don’t like this kind of lack of productivity or reliance on human judgment when I think it could be done much better algorithmically.
2. Use Existing Color Systems
Take Tailwind Colors, for example. It’s a very well-built color system. There are a lot of different hues, which makes it very versatile. The different shades within each hue are very consistent and broad, which makes them easy to use in projects, and honestly, I have no qualms with the system itself.
My issue when I use it is that it’s very generic. It’s widely available, it’s popular, and it’s well integrated into everyday software. So everybody uses it; in turn, that means if you use it, your project looks like every other project out there. Of course, you usually pick a hue or two for your branding, and for your everyday UI stuff, you use Tailwind colors.
It works, but I want something more, which is why I built Colors on the Curve (COTC).
How is Colors on the Curve different?
Colors on the Curve does not let you control the colors individually. That is honestly the main feature of this project and the main reason I built it.
You choose parameters for different curves that go through your color palette. You tell COTC that you want to make a palette of 15 colors and how the hues should be distributed along the 360-degree hue circle. Within each hue’s palette, you tell COTC whether you want the colors to shift slightly in hue as you move up the lightness values of the shades, making the hues change subtly as the palette progresses. You tell it how saturation changes across the shades, how light the lightest shade should be, how dark the darkest shade should be, and how the shades in between should determine their lightness values.
In the 3D space of HSL, you give each color a mathematically defined point, which you can then export and manually adjust slightly for different shades if needed. Maybe the hue shift should look slightly different for red and orange than it does for blue and cyan.
The project I was working on, and for which I needed this program, was intended for print. Since Figma does not natively support the CMYK color space, I had to implement a feature to detect whether colors are safe to use in CMYK, specifically when the combined percentages exceed 350%.
An issue I often run into when designing in RGB and converting to CMYK is that only the out-of-range colors get converted noticeably. So in Colors on the Curve, I built a feature that scales down all the colors in the same hue together into the CMYK color space if it detects that any one color falls outside it. This equally distributes the differences between each shade instead of leaving one color looking obviously off compared to the rest of the palette. (Of course, this would be possible in a traditional workflow if you knew early on that the design needed to be printed, but often you don’t.)
The project exports colors into a custom JSON format and also supports the Figma Variables JSON schema. That means you can export from Colors on the Curve and directly import the result into your Figma design file, letting you use your new color system across projects without doing everything manually.
There are still more features I would like to implement in Colors on the Curve:
- Parametric Bezier curve support
Currently, you can only use predefined curves: linear, parabolic, ease-in, ease-out, and ease-in-out. I would like to implement parametric cubic Beziers and make those predefined curves available as presets, for finer-grained control over how the different parameters move across the colors.
- Better palette visualization
Currently, COTC shows all the parameters as numeric values. I would like users to see how the colors are distributed in the color space and how changes to the parameters affect their placement in 3D space.
oklchsupport
Currently, COTC only supports HSL. I think it’s the most intuitive way to build colors, and it best represents the designer’s intent in terms of how they think about color. But I do understand the benefits of oklch, especially that its lightness value is based on perceived lightness, which means two different hues with the same lightness will appear similarly light. I’m just not sure how to translate the A/B parameters of the Lab color space into the model of Colors on the Curve in a way that works well.
- Breaking the spectrum into different palettes
I would like a feature where the colors built using Spectrum mode can be converted into individual palettes in Palettes mode, allowing for more fine-grained control over each palette.
That’s it for the functionality of Colors on the Curve, but there are more interesting things to say about its technical implementation. It is a single repository that builds to three different targets: an npm package, web, and TUI. I tried out some new features of the Bun bundler: single-file executables, standalone HTML compilation, and JavaScript APIs for bundling instead of relying on the Bun CLI, so you can have more control over the build process using JavaScript instead of Bash or something similar.
It was a cool technology to use and to try implementing myself. I will write more about the technical aspects of Colors on the Curve in the next post.
As always, you can find the source code for colors-on-the-curve at https://github.com/noidwasavailable/colors-on-the-curve, try out the webapp at https://colors-on-the-curve.pages.dev and get the npm package via npm install colors-on-the-curve.
Feel free to leave any suggestions, feedback, bug reports, pull requests or feature requests on the GitHub repository.