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

easing-gradient

v1.0.1

Published

Create smooth gradients that approximate easing functions

Readme

easing-gradient

npm GitHub License: MIT

Create smooth gradients that approximate easing functions.

CSS gradients (such as linear-gradient, radial-gradient, conic-gradient) interpolate linearly between their color stops. This often produces gradients that look harsh, muddy, or "banded" where two colors meet, because real-world color transitions rarely move in a straight line. easing-gradient fixes this by re-expressing a single eased transition as many tiny color stops (an "interpolation polyline"), so the browser renders a smooth, natural-looking gradient.

import { easingGradient } from "easing-gradient";

easingGradient("linear", "to right", [
  ["black", "0%", "ease"],
  ["transparent", "100%"],
]);

Why not just use a PostCSS plugin?

This project is inspired by larsenwork.com/easing-gradients and is based on the postcss-easing-gradients plugin by the same author Andreas Larsen. That plugin only works as a PostCSS transform, which forces you to write plain CSS files for it to take effect. If you use CSS-in-JS, or need to compute an eased gradient at runtime from plain JavaScript (e.g. in a Node.js environment), that approach becomes awkward.

easing-gradient is a plain, framework-agnostic JavaScript utility function. You can call it anywhere:

  • directly in a browser app;
  • in a Node.js script;
  • as the foundation of a plugin for a styling library — CSS-in-JS solutions (styled-components, Emotion, etc.) and atomic CSS frameworks (Tailwind CSS, etc.) alike.

Because it returns an ordinary CSS <gradient> string, whatever consumes CSS will accept its output.

Installation

# npm
npm install easing-gradient

# yarn
yarn add easing-gradient

# pnpm
pnpm add easing-gradient

# bun
bun add easing-gradient

The package ships ES modules and TypeScript declarations.

Usage

import { easingGradient } from "easing-gradient";

// Linear gradient easing from left to right.
easingGradient("linear", "to right", [
  ["green", "0%", "ease"],
  ["red", "100%"],
]);
// => "linear-gradient(to right, color-mix(in srgb-linear, green, red 0%), ...)"

// Radial gradient with an eased transition.
easingGradient("radial", "circle at top right", [
  ["red", "0%", "ease-in-out"],
  ["blue", "100%"],
]);

By default each transition is split into many interpolation stops. You can lower the number of stops to produce a smaller (but more "low-poly") gradient:

easingGradient("linear", undefined, [
  ["black", "0%", "cubic-bezier(0.48, 0.30, 0.64, 1.00)"],
  ["transparent", "100%"],
], { stops: 5 });
// => "linear-gradient(
//      color-mix(in srgb-linear, black, transparent 0%),
//      color-mix(in srgb-linear, black, transparent 28.281%) 30.813%,
//      color-mix(in srgb-linear, black, transparent 61.25%) 54.5%,
//      color-mix(in srgb-linear, black, transparent 88.594%) 75.938%,
//      color-mix(in srgb-linear, black, transparent 100%),
//      transparent
//    )"

API

easingGradient(type, towards, colorStops, options?)

Returns a CSS gradient string.

type

"linear" | "radial" | "conic" — the gradient function to generate.

| Value | Gradient function | | ---------- | ------------------- | | "linear" | linear-gradient() | | "radial" | radial-gradient() | | "conic" | conic-gradient() |

towards

The direction/shape argument for the gradient, or undefined to omit it. Examples: "to right", "to bottom left", "30deg", "circle at top right".

colorStops

An array of color stops. Each stop is a tuple [color, progress, easing?]:

| Index | Parameter | Type | Required | Description | | ----- | ---------- | -------------------- | -------- | -------------------------------------------------------------------------------------------------- | | 0 | color | string | Yes | The color at this stop. Any CSS color works: named colors, hex, rgb(), hsl(), etc. | | 1 | progress | string \| string[] | Yes | The stop position: a percentage ("0%", "100%"), a length ("20px"), or an array of these. | | 2 | easing | string | No | The CSS easing function applied to the transition into this stop. Defaults to "linear". |

The easing on a stop describes the transition into that stop (the segment that precedes it), because an easing function only shapes how interpolation moves between two color stops.

progress as an array

progress can also be an array, which expands into multiple stops sharing the same color.

This is the same behavior as it in CSS.

[["black", ["0%", "20%"]]]
// is equivalent to
[["black", "0%"], ["black", "20%"]]
A note on easing

Since easing only has meaning between two stops, the easing on the last color stop is ignored — there is nothing after it to interpolate toward. It's therefore best to omit easing on the final stop.

options

| Option | Type | Default | Description | | ------------------ | -------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------- | | stops | number | 13 | Interpolation points per eased segment. Lower values are more "low-poly" (less code, more banding). | | alphaDecimals | number | 3 | Decimal places for interpolated alpha values. Lower values can cause banding. | | colorMode | ColorSpace | "srgb-linear"| Color space used for interpolation. Passed to the CSS color-mix() function. | | colorMixFunction | (args: ColorMixFunctionArgument) => string | color-mix() | Custom function to compute each mixed color. See below. |

ColorSpace is one of hsl, hwb, lch, oklch, srgb, srgb-linear, display-p3, display-p3-linear, a98-rgb, prophoto-rgb, rec2020, lab, oklab, xyz, xyz-d50, xyz-d65.

Supported easing functions

Any CSS <easing-function> accepted by the underlying parser works as the easing argument:

  • keyword easings: linear, ease, ease-in, ease-out, ease-in-out
  • cubic-bezier(x1, y1, x2, y2)
  • steps(n, <jump>)
easingGradient("linear", "to right", [
  ["green", "0%", "steps(4, jump-none)"],
  ["red", "100%"],
]);

Custom color mixing

By default, interpolation uses the CSS-native color-mix() function. If you'd rather compute colors with your own color library (for wider browser support, or for a non-CSS target), pass a colorMixFunction.

colorMixFunction receives a single argument — an object with the following 7 properties:

| Property | Type | Description | | --------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | | colors | [string, string] | The two endpoint colors being mixed, as [startColor, endColor]. | | progress | string | The generated stop's position, e.g. "25%". When the stop positions are lengths rather than percentages, this is a calc(...) expression. | | progressValue | number | Numeric form of progress (e.g. 0.25 for "25%"). It is NaN when the positions are lengths, not percentages. | | amount | string | The interpolation amount as a percentage string, e.g. "42.5%". | | amountValue | number | Numeric form of amount (e.g. 0.425 for "42.5%"), in the range [0, 1]. | | alphaDecimals | number | The alphaDecimals option passed to easingGradient (or its default). | | colorMode | ColorSpace | The colorMode option passed to easingGradient (or its default). |

The function must return the resulting color as a string. Here is an example using chroma.js:

import chroma from "chroma-js";
import { easingGradient } from "easing-gradient";

easingGradient("linear", "to right", [["red", "0%", "ease"], ["blue", "100%"]], {
  colorMixFunction: ({ colors, amountValue, colorMode }) => {
    return chroma.mix(colors[0], colors[1], amountValue, colorMode);
  },
});

Building on top of this

easing-gradient is intentionally small and unopinionated so it can be wrapped into other tools. For example:

  • Tailwind CSS — expose it as a utility (or plugin) that generates an eased gradient value on demand.
  • CSS-in-JS — call it directly inside a styled component, or wrap it in a tagged-template helper.
  • Any runtime — use it in Node.js, Deno, Bun, or the browser without a build step for CSS.

Native support (CSSWG proposal)

Smooth gradients are a real problem being discussed at the CSS Working Group. If you'd like to see eased gradients built into browsers natively, please support this proposal:

If it ships, browsers will handle this natively and this library will have served its purpose.

Credits

License

MIT