Library / SDK
simonwep/pickr avatar
simonwep/pickr

Pickr: a flat, hackable color picker for plain JavaScript apps

🎨 Pickr - A simple, multi-themed, responsive and hackable Color-Picker library. No dependencies, no jQuery. Compatible with all CSS Frameworks e.g. Bootstrap, Materialize. Supports alpha channel, rgba, hsla, hsva and more!

4,489 stars291 forksJavaScriptMIT

At a glance

What is it?
Pickr is a dependency-free color picker widget that you mount on a DOM element and configure through a single options object. It is still receiving releases, but the README says its feature set is frozen and the author now recommends building this kind of widget directly in your framework.
Who is it for?
Adopt Pickr if you have a plain JavaScript or lightly frameworked page where a self-contained widget that mounts on a selector is the cheapest option, and if the frozen feature set is acceptable to you. Do not adopt it if you need ES5 output, since the README states there is no ES5 version as of v1.10.0, or if you want a component that follows your framework's rendering and state model.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 22 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Pickr solves, and who it is actually for

Every application that lets a user choose a color eventually needs the same set of controls: a hue strip, a saturation and value area, an opacity slider, and some way to type or read the value back. Building that from scratch means implementing color space conversions, pointer and touch handling, keyboard access, and popup positioning. Pickr packages those pieces into one widget you attach to an element.

The README describes it as a flat, simple, hackable color picker with no dependencies and no jQuery, compatible with CSS frameworks such as Bootstrap and Materialize. The intended user is an engineer working on a page or app that is not deeply coupled to a component framework, or one who wants a picker that does not pull in a runtime of its own. The repository ships three themes (classic, monolith, nano), and the README lists swatches, opacity control, mouse-wheel adjustment, touch support, i18n and Shadow DOM support among the features.

It is a widget, not a design system. You get the picker and its theming hooks; you do not get a form library, a validation layer, or a state container.

How Pickr is put together: one core file, an event API, and a popup

Pickr is event-driven. The README states that since version 0.4.x you bind and unbind listeners with the `on(event, cb)` and `off(event, cb)` functions on the instance. The documented events include `init`, which fires when initialization is done and Pickr can be used; `show`, which carries an HSVaColorObject and the instance; `hide`; and `save`, which fires when the user clicks the save or clear button and also fires on clear with `null` as the color.

That event surface matters because it is the boundary between the widget and your application. Pickr owns the popup, the pointer interactions and the conversion between color representations; your code owns what happens when the value changes. The README's feature list includes color comparison, which is the kind of thing that only makes sense if the instance holds both the original and the currently selected color.

The architecture is also the project's stated weakness. The README says the tool was built monolithically, with the core in one single file and everything in plain JS, and that this makes it hard to maintain and makes tests impossible at this stage without a complete rewrite. That is the author's own assessment, and it is the reason behind the feature freeze described below.

The frozen feature set is the first thing to read

The README carries an explicit notice: the project might continue to get important security and bug-related updates, but its feature set is frozen, and new features or enhancements are unlikely. The stated reason is the monolithic construction described above, plus the author's view that the complexity has become cramped.

The same notice goes further and recommends building these UI widgets directly into the app with whatever framework you use, naming (p)react, vue and svelte, on the grounds that it takes more time but gives you full control over behavior and appearance.

That is an unusual thing to find in a README, and it should shape how you read the rest of the documentation. The library is not abandoned: the last push to the repository was on 2026-09-08, and v1.10.2 was released the same day. But a frozen feature set means that if your requirement is not already covered by the options and events documented today, you should expect to implement it yourself rather than wait for it.

Installing Pickr and mounting a first picker

The README gives two installation paths. For a bundler-based project, install the package from npm or yarn. Note the scoped package name, `@simonwep/pickr`.

bash
npm install @simonwep/pickr

or

bash
yarn add @simonwep/pickr

Then import one of the three theme stylesheets and the library itself. The README shows the imports in this order, with the theme first, and notes that your bundler will pick the correct import for you.

js
// One of the following themes
import '@simonwep/pickr/dist/themes/classic.min.css';   // 'classic' theme
import '@simonwep/pickr/dist/themes/monolith.min.css';  // 'monolith' theme
import '@simonwep/pickr/dist/themes/nano.min.css';      // 'nano' theme

// Your bundler will pick the correct import for you
import Pickr from '@simonwep/pickr';

For a plain browser page, the README uses jsdelivr and offers both an ES module and a UMD build. Two constraints are stated plainly: load `pickr.min.js` after `pickr.min.css`, and the script tag does not work with the `defer` attribute.

html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script>

The first real use is a single call to `Pickr.create` with an element selector and a theme. The README's simple example passes `el`, `theme`, a `swatches` array, and a `components` object that turns the preview, opacity and hue controls on and off, and selects which interaction inputs appear: hex, rgba, hsla, hsva, cmyk, a free-form input, clear and save.

javascript
const pickr = Pickr.create({
    el: '.color-picker',
    theme: 'classic', // or 'monolith', or 'nano'
    swatches: [
        'rgba(244, 67, 54, 1)',
        'rgba(233, 30, 99, 0.95)'
    ],
    components: {
        preview: true,
        opacity: true,
        hue: true,
        interaction: {
            hex: true,
            rgba: true,
            input: true,
            clear: true,
            save: true
        }
    }
});

What you should see is the picker bound to the element matching `.color-picker`, with the controls you enabled in `components`. If nothing appears, check the stylesheet import first: the widget's layout comes from the theme CSS, and the README places the CSS before the script for exactly that reason. The README points to EXAMPLES.md for more configurations.

Where Pickr stops being the right choice

The hard limitation is stated in the README as a warning: as of v1.10.0 there is no ES5 version anymore, and if you need to support older browsers you should consult your bundler's docs for how to transpile dependencies. That is a build-pipeline requirement, not a runtime option, and it lands on you rather than on the library.

The second constraint is per-theme. The README notes that the nano theme uses CSS grid and therefore will not work in older browsers. So the theme choice is not purely visual; it carries a browser-support decision with it.

The third is the feature freeze. If your design calls for a control the options do not expose, the README's own position is that you should build the widget in your framework instead. Pickr is a poor fit when the picker is central to your product's interaction model and you expect to iterate on it. It is a reasonable fit when the picker is a supporting control on a form and the documented options cover your case.

There is also a practical boundary in the browser path: the script tag does not work with `defer`, which rules out one of the more common ways of loading scripts without blocking.

Pickr versus building the picker in your framework

The most credible alternative here is not another library. It is the one the README names: writing the widget yourself with the framework you already use, in (p)react, vue or svelte. The difference in approach is ownership of rendering and state. Pickr creates its own DOM, manages its own popup and positioning, and exposes an event API (`init`, `show`, `hide`, `save`) for you to hook into. A framework-native picker instead participates in your component tree, so its open state, its selected color and its lifecycle are ordinary reactive state rather than something you synchronize through callbacks.

The trade is explicit in the README: building it yourself takes more time, but in return you get full control of how it works and looks. Pickr's counter-argument is speed of adoption. One `Pickr.create` call with an options object gets you hue, opacity, swatches, multiple color representations and accessibility without writing color space conversions or pointer handling.

If your app is plain JavaScript or server-rendered HTML with a little scripting, that trade favors Pickr. If your app is a component tree where every other control is a component, the event bridge becomes the awkward part, and the README's recommendation to build in-framework is worth taking seriously.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-08, with v1.10.2 released that day. Releases in the recent series are v1.10.0 on 2026-07-18, v1.10.1 on 2026-07-29 and v1.10.2 on 2026-09-08. The README's own framing is that security and bug-related updates may continue while features do not, so plan for a dependency that receives fixes rather than one that grows.

Upgrade cost is concentrated in the v1.10.0 line. Dropping the ES5 build means consumers who target older browsers must handle transpilation themselves, so an upgrade across that boundary is a build change, not just a version bump. The README also tells you the readme tracks the latest commit and that you should check Releases for installation instructions for a specific version, which is a sensible practice given that the documented import paths point at the `dist` directory.

The licence is MIT, declared in both the README badge area and the package.json `license` field. That is a permissive licence, but this is not legal advice and the obligations that apply to your distribution depend on your own counsel's reading of the LICENSE file in the repository.

Editorial conclusion

Adopt Pickr if you have a plain JavaScript or lightly frameworked page where a self-contained widget that mounts on a selector is the cheapest option, and if the frozen feature set is acceptable to you. Do not adopt it if you need ES5 output, since the README states there is no ES5 version as of v1.10.0, or if you want a component that follows your framework's rendering and state model. Before committing, verify three things: that your bundler transpiles dependencies if you must support older browsers, that the theme you want (nano uses CSS grid) matches your browser targets, and that you can live with the author's own recommendation to build the widget in-framework instead.

Frequently asked questions

How do I install Pickr in a project that uses a bundler?

Install the scoped package with `npm install @simonwep/pickr` or `yarn add @simonwep/pickr`, then import one of the theme stylesheets from `@simonwep/pickr/dist/themes/` and import Pickr from `@simonwep/pickr`. The README shows the theme import placed before the library import.

Does Pickr still support older browsers that need ES5 output?

The README states that as of v1.10.0 there is no ES5 version anymore, and that if you need to support older browsers you should consult your bundler's documentation for transpiling dependencies. The nano theme additionally uses CSS grid and will not work in older browsers.

Why does the Pickr README say the feature set is frozen?

The README says the project may keep getting important security and bug-related updates, but new features are unlikely. It gives the monolithic construction, with the core in one single file and everything in plain JS, as the reason, and recommends building this kind of widget directly in your framework instead.

How do I react to a user picking a color in Pickr?

Pickr is event-driven. The README documents binding listeners with `on(event, cb)` and unbinding with `off(event, cb)`, and lists events including `init`, `show`, `hide` and `save`. The `save` event fires when the user clicks the save or clear button, and also fires on clear with `null` as the color.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. simonwep/pickr on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/simonwep-pickr.svg)](https://hysenlabs.com/projects/simonwep-pickr)