# Colorshot React Color Picker with Gradients – Orshot

- **URL**: https://orshot.com/open-source/colorshot

---

Open source by Orshot

# Color and Gradient Picker for React and Vue

Solid colors, linear, radial and conic gradients, your own swatch groups and an eyedropper. It takes plain CSS strings and hands them back.

$npm i @orshot/colorshotCopy agent prompt[Docs](#docs)

MIT licensed · v0.2.0 · React 18+ and Vue 3

Swipe with two fingers on the area to pick colors fast

Alt drag a stop to copy it, drag it off the bar to remove it

Click the picker, then press 1–4 to switch modes or ⌘V to paste any CSS color

#3E5CEB

SolidLinearRadialConic

0%52%100%

360.0135°1000%

HEX

#100100%

GradientsBrand

`linear-gradient(135deg, #3E5CEB 0%, #A855F7 52%, #F97316 100%)`

4 gradient typesLinear, radial, conic and repeating, with draggable stops

10 color formatsHEX, RGB, HSL, HSB, OKLCH, OKLAB, LCH, LAB, Display P3, CMYK

WCAG 2.2 AAChecked with axe. Keyboard, screen readers, high contrast, RTL

1 update per frameDragging re-renders only the parts that change

44 KB gzippedReact app with styles, zero dependencies

450 testsIn Chromium, Firefox and WebKit, plus 31,731 real colors

Try it

## A React color picker with every gradient type built in

Linear, radial, conic and repeating gradients, your brand colors, trackpad gestures and a contrast check, in one component for React or Vue. Every card below is live.

### Linear, radial, conic and repeating

Edit every CSS gradient type, with angle, center, shape and as many stops as you like.

LinearRadialConicRepeating

#3E5CEB

SolidLinearRadialConic

0%50%100%

360.0135°1000%

### Two-finger swipe

On a trackpad, swipe to move the color area, sliders, stops and angle. The page still scrolls everywhere else.

#304FE8

### Stops that move like objects

Swipe a stop along the bar, or use the gestures you know from design tools.

Swipe to moveAlt-drag to copyDrag off to removeClick to add

0%50%100%

### Gradient handles on your canvas

Draw start and end handles right on the design, like Figma. Two helper functions give your editor the same handles.

`gradientHandles(value, width, height)`

Drag the handles

### Paste any CSS color

Hex, rgb, hsl, oklch, named or display-p3\. Press Cmd+V in the picker.

reads as #663399

#3e5cebhsl(160 84% 39%)oklch(0.72 0.19 45)rebeccapurplecolor(display-p3 0.2 0.8 0.6)

### Contrast as you pick

A WCAG badge against your background. For gradients it checks the weakest stop.

Summer SaleUp to 40% off, this weekend only

Contrast5.34:1AA

### Brand and saved colors

Your own swatch groups, with add, remove, rename, reorder and search.

Brand

* Never crashes on bad dataUnknown or broken values show as unsupported and stay untouched.
* Keyboard and screen readerEvery control works by keyboard, is labelled and supports right to left.
* Light, dark and your themeMatch your app with a few --cs-\* CSS variables.
* Undo, eyedropper, copy and pasteCmd+Z inside the picker, a screen eyedropper, Cmd+C and Cmd+V.

In production

## Play with Colorshot live, select a layer

This is the real Orshot Studio, embedded on this page. Click any color in the panel to open Colorshot. Nothing you change is saved.

CarouselAnimated adVideo short

Loading the editor…

Select a shape, then click its fill color to open Colorshot.

Documentation

## Add it to your app in a few minutes

### Install

One package. Your app only bundles the entry it imports, and React and Vue are optional peers.

npmpnpmyarnbun

```
npm i @orshot/colorshot
```

```
pnpm add @orshot/colorshot
```

```
yarn add @orshot/colorshot
```

```
bun add @orshot/colorshot
```

| Import                       | What it is                                                                 |
| ---------------------------- | -------------------------------------------------------------------------- |
| @orshot/colorshot/react      | React components and hooks                                                 |
| @orshot/colorshot/vue        | Vue components and composables                                             |
| @orshot/colorshot            | Color math, CSS gradient parsing and the picker store. Safe in server code |
| @orshot/colorshot/styles.css | The stylesheet, imported once                                              |

### Quick start

value is any CSS color or gradient. onChange fires while dragging, onChangeComplete once when the change is done.

ReactVueNo framework

```
"use client";

import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";
import "@orshot/colorshot/styles.css";

export function FillPicker() {
  const [fill, setFill] = useState("linear-gradient(135deg, #3E5CEB 0%, #22C55E 100%)");

  return (
    <ColorPicker
      value={fill}
      onChange={setFill} // every frame while dragging
      onChangeComplete={(value) => save(value)} // once, when the change is done
    />
  );
}
```

```
<script setup>
import { ref } from "vue";
import { ColorPicker } from "@orshot/colorshot/vue";
import "@orshot/colorshot/styles.css";

const fill = ref("#3E5CEB");
</script>

<template>
  <ColorPicker v-model="fill" @change-complete="save" />
</template>
```

```
import { createPicker, parseColor, formatColor } from "@orshot/colorshot";

// The same store the React and Vue pickers use, safe in server code too
const picker = createPicker({
  value: "#3E5CEB",
  onChange: (value) => console.log(value),
});

picker.setHsva({ h: 140 });
picker.commit();

formatColor(parseColor("rgb(62 92 235 / 50%)").color, "hex"); // "#3e5ceb80"
```

### With a coding agent

Paste this into Claude Code, Cursor or Codex. It installs Colorshot and swaps your pickers after you confirm the list.

Setup promptCopy prompt

Add Colorshot (@orshot/colorshot), an open source color and gradient picker, to this project.

1. Install it with this project's package manager: npm i @orshot/colorshot
2. Import the stylesheet once, in the app's root layout or entry file: import "@orshot/colorshot/styles.css"
3. Use the entry for this project's framework:
   - React: import { ColorPicker, ColorField } from "@orshot/colorshot/react"
   - Vue: import { ColorPicker, ColorField } from "@orshot/colorshot/vue"
   - No framework: import { createPicker } from "@orshot/colorshot"
4. ColorPicker takes and returns plain CSS strings: value is any CSS color or gradient, onChange fires while dragging, onChangeComplete fires once when the change is done (save there).
5. Use ColorField when a field should open the picker in a popover.
6. Pass modes={["solid"]} where gradients are not allowed, and alpha={false} where transparency is not allowed.
7. In Next.js, render the picker from a client component ("use client").

Find the color inputs and pickers in this codebase, show me the list, and replace the ones I confirm. Keep the stored value format the same, and run the existing tests after.

Full API reference: https://orshot.com/open-source/colorshot

Or install the Colorshot skill, so your agent knows the API in every session. The full reference for LLMs is in [llms.txt](https://github.com/rishimohan/colorshot/blob/main/llms.txt).

```
npx skills add rishimohan/colorshot
```

### ColorPicker

The ready-made panel: area, sliders, every gradient mode, inputs and swatch groups.

PreviewCode

#3E5CEB

SolidLinearRadialConic

0%100%

360.0135°1000%

HEX

#100100%

Gradients

`linear-gradient(135deg, #3E5CEB 0%, #F97316 100%)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

export function Example() {
  const [value, setValue] = useState("linear-gradient(135deg, #3E5CEB 0%, #F97316 100%)");
  return <ColorPicker value={value} onChange={setValue} gradientPresets swatchSearch />;
}
```

### ColorField

A field that opens the picker in a popover. It flips and shifts to stay on screen, closes on Escape or an outside click, and returns focus.

PreviewCode

#3E5CEB

Click the field to open the picker

```
import { useState } from "react";
import { ColorField } from "@orshot/colorshot/react";

export function Example() {
  const [fill, setFill] = useState("#3E5CEB");
  // takes every ColorPicker prop, plus placement, portal and a custom trigger
  return <ColorField label="Fill" value={fill} onChange={setFill} gradientPresets />;
}
```

| Prop                              | Type                           | What it does                                               |         |             |            |                                                        |
| --------------------------------- | ------------------------------ | ---------------------------------------------------------- | ------- | ----------- | ---------- | ------------------------------------------------------ |
| label / placeholder               | string                         | Trigger label, and the text shown when the value is empty. |         |             |            |                                                        |
| placement                         | bottom-start \| bottom-end     | top-start                                                  | top-end | right-start | left-start | Preferred side. It flips and shifts to stay on screen. |
| open / defaultOpen / onOpenChange | boolean, (open) => void        | Control the popover, or leave it uncontrolled.             |         |             |            |                                                        |
| portal                            | boolean \| HTMLElement         | Render the popover elsewhere in the DOM.                   |         |             |            |                                                        |
| renderTrigger                     | ({ value, open }) => ReactNode | Your own trigger button.                                   |         |             |            |                                                        |
| pickerClassName / pickerStyle     | string, CSSProperties          | Style the picker inside the popover.                       |         |             |            |                                                        |
| ...ColorPicker props              |                                | Every ColorPicker prop works here too.                     |         |             |            |                                                        |

### Parts

Build your own layout from the same parts the ready-made picker uses. Picker.Root holds the state; put any parts inside it.

A compact solid picker

PreviewCode

#22C55E

#

`#22C55E`

```
import { useState } from "react";
import { Picker } from "@orshot/colorshot/react";

// Your own layout: a compact solid picker with only an area, hue and a hex field
export function Example() {
  const [value, setValue] = useState("#22C55E");
  return (
    <Picker.Root value={value} onChange={setValue} modes={["solid"]}>
      <Picker.Area />
      <Picker.Hue />
      <Picker.Inputs formats={["hex"]} alpha={false} />
    </Picker.Root>
  );
}
```

A brand palette, swatches only

PreviewCode

Brand

`#3E5CEB`

```
import { useState } from "react";
import { Picker } from "@orshot/colorshot/react";

// A brand palette with no free picking: swatches only
export function Example() {
  const [value, setValue] = useState("#3E5CEB");
  return (
    <Picker.Root value={value} onChange={setValue} modes={["solid"]}>
      <Picker.Swatches groups={[{ id: "brand", label: "Brand", colors: BRAND_COLORS }]} />
    </Picker.Root>
  );
}
```

| Part                                                          | What it is                                                                         |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Picker.Root                                                   | The panel and the state every other part reads. Takes the ColorPicker value props. |
| Picker.Area                                                   | The 2D saturation and brightness area.                                             |
| Picker.Hue / Picker.Alpha                                     | The hue and opacity sliders.                                                       |
| Picker.ModeTabs                                               | Solid, Linear, Radial and Conic tabs.                                              |
| Picker.GradientEditor                                         | Bar plus controls, shown only in gradient modes.                                   |
| Picker.GradientBar                                            | The stop bar on its own.                                                           |
| Picker.GradientControls / Picker.AngleDial / Picker.CenterPad | Angle, shape, size and center controls.                                            |
| Picker.Inputs                                                 | Format menu and channel fields (hex, rgb, hsl, ...).                               |
| Picker.EyeDropper                                             | Screen color picking where the browser supports it.                                |
| Picker.Swatches                                               | Swatch groups with tabs, search, add and remove.                                   |
| Picker.CurrentSwatch / Picker.Preview                         | The current value, with an optional before and after.                              |
| Picker.Contrast                                               | WCAG contrast badge against a background.                                          |
| Picker.Notice                                                 | Shown when a value cannot be read.                                                 |

### Linear gradient

One mode, no tabs. Drag the stops, Alt-drag one to duplicate it, drag it off the bar to remove it. The dial sets the angle.

PreviewCode

#22C55E

0%100%

360.090°1000%

HEX

#100100%

`linear-gradient(90deg, #22C55E 0%, #3E5CEB 100%)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// A linear gradient picker: drag the stops, Alt-drag to duplicate one,
// drag a stop off the bar to remove it. The angle dial sets the direction.
export function Example() {
  const [value, setValue] = useState("linear-gradient(90deg, #22C55E 0%, #3E5CEB 100%)");
  return <ColorPicker value={value} onChange={setValue} modes={["linear"]} />;
}
```

### Radial gradient

The center pad moves the center and switches between circle and ellipse. Size and repeating are in the ... menu.

PreviewCode

#FDE68A

0%45%100%

CircleEllipse

HEX

#100100%

`radial-gradient(circle at 30% 30%, #FDE68A 0%, #F97316 45%, #BE123C 100%)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// A radial gradient picker: drag the center pad to move the center and switch
// between circle and ellipse. The size keyword and Repeating live in the ... menu.
export function Example() {
  const [value, setValue] = useState(
    "radial-gradient(circle at 30% 30%, #FDE68A 0%, #F97316 45%, #BE123C 100%)",
  );
  return <ColorPicker value={value} onChange={setValue} modes={["radial"]} />;
}
```

### Conic gradient

The dial sets the start angle and the center pad moves the center. Good for color wheels and pie-like fills.

PreviewCode

#EF4444

0%20%40%60%80%100%

360.00°1000%

HEX

#100100%

`conic-gradient(from 0deg at 50% 50%, #EF4444, #F59E0B, #22C55E, #3B82F6, #A855F7, #EF4444)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// A conic gradient picker: the angle dial sets the start angle,
// the center pad moves the center.
export function Example() {
  const [value, setValue] = useState(
    "conic-gradient(from 0deg at 50% 50%, #EF4444, #F59E0B, #22C55E, #3B82F6, #A855F7, #EF4444)",
  );
  return <ColorPicker value={value} onChange={setValue} modes={["conic"]} />;
}
```

### Gradients only

For backgrounds that must be a gradient. defaultGradient is what a solid value turns into, and presets give people a place to start.

PreviewCode

#F472B6

LinearRadialConic

0%100%

360.0135°1000%

HEX

#100100%

Gradients

`linear-gradient(135deg, #F472B6 0%, #6366F1 100%)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// Backgrounds that must be a gradient: no Solid tab, preset gradients to start from.
export function Example() {
  const [value, setValue] = useState("linear-gradient(135deg, #F472B6 0%, #6366F1 100%)");
  return (
    <ColorPicker
      value={value}
      onChange={setValue}
      modes={["linear", "radial", "conic"]}
      defaultGradient="linear-gradient(90deg, #3E5CEB 0%, #22C55E 100%)"
      gradientPresets
    />
  );
}
```

### Solid colors only

For fields where a gradient or transparency makes no sense, like a brand accent.

PreviewCode

#A855F7

HEX

#

`#A855F7`

```
<ColorPicker
  value={value}
  onChange={setValue}
  modes={["solid"]} // no gradient tabs
  alpha={false} // no opacity slider or field
  formats={["hex", "rgb", "hsl"]}
/>
```

### Text color with contrast

contrastWith shows the WCAG contrast ratio against the background and draws the AA line on the color area.

PreviewCode

#64748B

HEX

#

Contrast4.76:1AA

Body text on a white page

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// A text color on a white page: solid only, no transparency,
// and a WCAG contrast badge against the background.
export function Example() {
  const [value, setValue] = useState("#64748B");
  return (
    <ColorPicker
      value={value}
      onChange={setValue}
      modes={["solid"]}
      alpha={false}
      contrastWith="#FFFFFF"
    />
  );
}
```

### OKLCH and wide gamut

Edit in a perceptual space. The area is drawn in Display P3 where the screen supports it, and a dashed line marks the edge of sRGB.

PreviewCode

62% 0.2 265°

OKLCH

100620.0000.2360265100100%

`oklch(0.62 0.2 265)`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// Perceptual editing: the area is OKLCH lightness by chroma, drawn in Display P3
// where the screen supports it. A dashed line marks the edge of sRGB.
export function Example() {
  const [value, setValue] = useState("oklch(0.62 0.2 265)");
  return (
    <ColorPicker
      value={value}
      onChange={setValue}
      modes={["solid"]}
      space="oklch"
      formats={["oklch", "hex", "rgb"]}
      outputFormat="oklch"
    />
  );
}
```

### Undo and compare

history adds Cmd/Ctrl+Z inside the picker. compare splits the header swatch into before and after.

PreviewCode

#F97316

SolidLinearRadialConic

HEX

#100100%

`#F97316`

```
import { useState } from "react";
import { ColorPicker } from "@orshot/colorshot/react";

// Cmd/Ctrl+Z and Shift+Cmd/Ctrl+Z inside the picker. The header swatch splits
// into before and after once the value changes; click "before" to restore.
export function Example() {
  const [value, setValue] = useState("#F97316");
  return <ColorPicker value={value} onChange={setValue} history compare />;
}
```

### In a form

ColorField works with any form library. It takes a value and an onChange like an input, and submits a plain CSS string.

```
"use client";

import { Controller, useForm } from "react-hook-form";
import { ColorField } from "@orshot/colorshot/react";

// A settings form: the field opens the picker in a popover and submits a plain CSS string.
export function BrandForm({ onSubmit }) {
  const { control, handleSubmit } = useForm({
    defaultValues: { accent: "#3E5CEB", background: "linear-gradient(135deg, #0F172A 0%, #1E293B 100%)" },
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="accent"
        control={control}
        render={({ field }) => (
          <ColorField label="Accent" value={field.value} onChange={field.onChange} modes={["solid"]} alpha={false} />
        )}
      />
      <Controller
        name="background"
        control={control}
        render={({ field }) => (
          <ColorField label="Background" value={field.value} onChange={field.onChange} gradientPresets />
        )}
      />
      <button type="submit">Save</button>
    </form>
  );
}
```

### Saving changes

onChange fires on every frame of a drag. Update the preview there, and save or record undo in onChangeComplete, which fires once.

```
// Update the canvas on every frame, save once when the drag ends.
<ColorPicker
  value={layer.fill}
  onChange={(fill) => updateLayerPreview(layer.id, { fill })}
  onChangeComplete={(fill) => saveLayer(layer.id, { fill })}
/>
```

### With shadcn/ui

Add it with the shadcn CLI. You get a color-picker component that uses your theme tokens and switches with your dark mode.

$npx shadcn@latest add https://orshot.com/r/color-picker.json

```
import { ColorField, ColorPicker } from "@/components/ui/color-picker";

<ColorPicker value={fill} onChange={setFill} />
<ColorField label="Accent" value={accent} onChange={setAccent} />
```

```
/* Or theme the package yourself in globals.css, with the same tokens the component uses.
   On a Tailwind v3 theme (HSL channel tokens) wrap them: hsl(var(--popover)) */
[data-colorshot],
[data-colorshot-field] {
  --cs-bg: var(--popover);
  --cs-fg: var(--popover-foreground);
  --cs-muted: var(--muted-foreground);
  --cs-border: var(--border);
  --cs-surface: var(--muted);
  --cs-surface-hover: var(--accent);
  --cs-accent: var(--ring);
}
```

### Swatch groups

Each group becomes a tab. Add onAdd and onRemove to let people save and delete colors.

```
<ColorPicker
  value={value}
  onChange={setValue}
  swatchSearch
  swatches={[
    {
      id: "brand",
      label: "Brand",
      colors: [{ value: "#3E5CEB", label: "Tide" }, "#0A0A0A", "#F5F5F5"],
      onAdd: (value) => saveBrandColor(value), // shows a + button
      onRemove: (swatch) => deleteBrandColor(swatch),
    },
    { id: "recent", label: "Recent", recent: true },
  ]}
/>
```

### Output format

By default a picked color keeps the format of the value. Pass outputFormat to write the format your app stores.

```
import { formatColor } from "@orshot/colorshot";

// Orshot's own setting: uppercase hex when opaque, comma rgba when not.
// Gradients keep their shape; edited stops use the same format.
function outputFormat(color) {
  if (color.alpha >= 1) return formatColor({ ...color, alpha: 1 }, "hex", { upper: true });
  return formatColor(color, "rgb", { legacy: true, fn: "rgba" });
}

<ColorPicker value={value} onChange={setValue} outputFormat={outputFormat} />
```

### Theming

Light and dark are built in. Everything else is a CSS variable you set on the picker.

PreviewCode

#FDE68A

SolidLinearRadialConic

0%45%100%

CircleEllipse

HEX

#100100%

`radial-gradient(circle at 30% 30%, #FDE68A 0%, #F97316 45%, #BE123C 100%)`

```
<ColorPicker
  value={value}
  onChange={setValue}
  theme="dark"
  style={{
    "--cs-accent": "#E11D48",
    "--cs-radius": "20px",
    "--cs-radius-control": "10px",
  }}
/>
```

```
/* on the picker: a class, its style prop or a [data-colorshot] rule */
.my-panel [data-colorshot] {
  --cs-accent: #3e5ceb;
  --cs-radius: 12px;
  --cs-width: 280px;
}
```

```
/* The variables sit in @layer colorshot, so your own CSS sets them
   without !important. CSS resets such as Tailwind's preflight cannot restyle the picker */
.inspector [data-colorshot] {
  --cs-width: 100%;
  --cs-area-height: 160px;
}
```

| Variable             | What it sets                    |
| -------------------- | ------------------------------- |
| \--cs-accent         | Focus rings and selected states |
| \--cs-bg / --cs-fg   | Panel background and text       |
| \--cs-radius         | Panel corners                   |
| \--cs-width          | Panel width                     |
| \--cs-area-height    | Height of the color area        |
| \--cs-swatch-columns | Swatches per row                |
| \--cs-shadow         | Panel shadow                    |

### Localization

Every visible and screen reader string is a label you can replace.

```
// Every visible and screen reader string is a label. {placeholders} are filled in for you.
<ColorPicker
  value={value}
  onChange={setValue}
  labels={{
    picker: "Farbwähler",
    solid: "Einfarbig",
    linear: "Linear",
    radial: "Radial",
    conic: "Konisch",
    hue: "Farbton",
    alpha: "Deckkraft",
    stopName: "Farbstopp {index} von {count}",
  }}
/>
```

### Gradient handles on your canvas

Show start, end, stop and center handles on the selected layer, like Figma. Two framework-free helpers do the math.

```
import { gradientHandles, moveGradientHandle } from "@orshot/colorshot";

// Handles for the selected layer, in its own pixel space
const result = gradientHandles(layer.fill, layer.width, layer.height); // null when not a gradient

result?.handles.forEach((h) => drawHandle(h.x, h.y, h.kind, h.color)); // start, end, stops, center
if (result?.line) drawGuide(result.line);

// On pointer move while dragging a handle
layer.fill = moveGradientHandle(layer.fill, handle.id, x, y, layer.width, layer.height, { snap: event.shiftKey });
```

### Keyboard and gestures

Built in, no props needed. Shortcuts work while the picker has focus.

| Input                      | What it does                                            |
| -------------------------- | ------------------------------------------------------- |
| Two-finger swipe           | Move the area, sliders, stops and angle on a trackpad   |
| Arrow keys                 | Nudge the focused thumb, stop or field (Shift for 10x)  |
| 1 to 4                     | Switch Solid, Linear, Radial and Conic (picker focused) |
| I                          | Open the eyedropper                                     |
| ⌘C / ⌘V                    | Copy the value, or paste any CSS color or gradient      |
| ⌘Z / ⇧⌘Z                   | Undo and redo, with the history prop                    |
| Click the bar / Enter      | Add a stop                                              |
| Alt + drag a stop          | Copy the stop                                           |
| Drag off the bar / Delete  | Remove a stop                                           |
| Drag a swatch onto the bar | Add it as a stop                                        |
| Escape                     | Drop what you typed, or close a ColorField              |

### Optional features

Off unless you turn them on.

| Prop                 | What it does                                                                |
| -------------------- | --------------------------------------------------------------------------- |
| space="oklch"        | A perceptual OKLCH area and hue slider, drawn in Display P3 where supported |
| history              | Undo and redo committed changes with Cmd/Ctrl+Z inside the picker           |
| contrastWith="#fff"  | WCAG contrast badge; gradients use their weakest stop                       |
| compare              | Before and after swatch; click before to restore                            |
| tabIcons             | Icons next to the Solid, Linear, Radial and Conic labels                    |
| swatchLayout="stack" | List every swatch group instead of one tab per group                        |
| size="sm"            | Compact: 240px wide, 24px controls                                          |
| variant="inset"      | Mode tabs first and a framed area, instead of the edge-to-edge area         |
| eyeDropper={fn}      | Your own screen picker for browsers without the native EyeDropper           |
| shortcuts={false}    | Turn off 1 to 4 and I                                                       |
| storageKey={null}    | Keep recent colors and the chosen format in memory only                     |

### Core helpers

Framework-free functions from @orshot/colorshot. Safe in server code, and none of them throw on bad input.

| Function                                       | What it does                                                     |
| ---------------------------------------------- | ---------------------------------------------------------------- |
| createPicker(options)                          | The framework-free store the React and Vue pickers use.          |
| parseColor(css)                                | Any CSS color to { color, format }, or null. Never throws.       |
| formatColor(color, format, style?)             | Write a color as hex, rgb, hsl, oklch, p3 and more.              |
| isGradient / parseGradient / serializeGradient | Read and write CSS gradients, keeping what you did not edit.     |
| gradientHandles / moveGradientHandle           | Start, end, stop and center handles for your own canvas.         |
| contrastRatio(fg, bg) / contrastLevel(ratio)   | WCAG contrast and its AA or AAA level.                           |
| isSafeCssValue / safeCssValue                  | Only plain colors and gradients, before a value reaches a style. |

### ColorPicker props

The ones you will reach for. The README on GitHub lists every prop.

| Prop             | Type                        | What it does                                                                         |
| ---------------- | --------------------------- | ------------------------------------------------------------------------------------ |
| value            | string                      | Any CSS color or gradient. Unknown text is shown as unsupported and left as it is.   |
| onChange         | (value) => void             | Fires while dragging or typing, at most once per frame.                              |
| onChangeComplete | (value) => void             | Fires once when a change ends. Save and record undo here.                            |
| modes            | PickerMode\[\]              | Any of solid, linear, radial, conic. Default: all four.                              |
| outputFormat     | string \| (color) => string | How picked colors are written. Default keeps the format of the value.                |
| alpha            | boolean                     | Show the opacity slider and field. Default true.                                     |
| formats          | DisplayFormat\[\]           | Formats in the input menu, for example hex, rgb, hsl, hsb, cmyk.                     |
| swatches         | SwatchGroupConfig\[\]       | Your swatch groups: brand, saved, recent, with add and remove.                       |
| swatchSearch     | boolean                     | Search every group by name, value or hex.                                            |
| gradientPresets  | boolean \| string\[\]       | Gradient swatches in gradient modes.                                                 |
| theme            | light \| dark               | Force a theme. Default follows the OS.                                               |
| size             | sm                          | Compact: 240px wide, 24px controls.                                                  |
| storageKey       | string \| null              | Where recent colors and the chosen format are remembered. null keeps them in memory. |

### TypeScript

Types ship with the package, for every entry.

```
import type { ColorPickerProps, SwatchGroupConfig, Swatch } from "@orshot/colorshot/react";
import type { OutputFormat, PickerMode, Color } from "@orshot/colorshot";
```

FAQ

## Questions

### Is Colorshot free to use?

Yes. It is MIT licensed, so you can use it in personal and commercial projects.

### Does it work with Next.js?

Yes. Render the picker from a client component ("use client"). The framework-free entry, @orshot/colorshot, is safe to import in server code.

### Will it break on colors my app already stores?

No. Before release we ran every color in Orshot's production templates through it, 31,731 distinct values. Anything it cannot read is shown as unsupported and left as it is.

### Does it work with shadcn/ui?

Yes. Run npx shadcn@latest add https://orshot.com/r/color-picker.json to add a color-picker component that uses your theme tokens and switches with your dark mode. Or install the package and map its CSS variables to your tokens yourself.

### Is there a Vue color picker too?

Yes. The same picker ships for Vue 3 from @orshot/colorshot/vue, with v-model support.

### How big is it?

About 44 KB gzipped for a React app, styles included, with zero dependencies. A React app never loads the Vue code, and the reverse.

### Who maintains it?

Orshot, the API for automated image, PDF and video generation. Colorshot is the picker inside the Orshot template editor.

Made by Orshot

## Colorshot powers Orshot Studio, _with 10k+ users_

Orshot is an API that generates images, PDFs and videos from your templates.

[Start for free →](https://orshot.com/pricing)[Star on GitHub](https://github.com/rishimohan/colorshot)

DataTemplateDeliveredAPI![](https://orshot.com/third-party-icons/n8n.png)n8n![](https://orshot.com/third-party-icons/make.jpeg)Make![](https://orshot.com/home/new/flow/ugc-a-1.webp)![](https://orshot.com/home/new/flow/ugc-a-2.webp)![](https://orshot.com/home/new/flow/ugc-a-3.webp)RenderingMP4![](https://orshot.com/third-party-icons/tiktok.svg)TikTokPNG![](https://orshot.com/third-party-icons/instagram.svg)InstagramPDF![](https://orshot.com/third-party-icons/google-drive.svg)Drive

## FAQ

### Is Colorshot free to use?

Yes. It is MIT licensed, so you can use it in personal and commercial projects.

### Does it work with Next.js?

Yes. Render the picker from a client component ("use client"). The framework-free entry, @orshot/colorshot, is safe to import in server code.

### Will it break on colors my app already stores?

No. Before release we ran every color in Orshot's production templates through it, 31,731 distinct values. Anything it cannot read is shown as unsupported and left as it is.

### Does it work with shadcn/ui?

Yes. Run npx shadcn@latest add https://orshot.com/r/color-picker.json to add a color-picker component that uses your theme tokens and switches with your dark mode. Or install the package and map its CSS variables to your tokens yourself.

### Is there a Vue color picker too?

Yes. The same picker ships for Vue 3 from @orshot/colorshot/vue, with v-model support.

### How big is it?

About 44 KB gzipped for a React app, styles included, with zero dependencies. A React app never loads the Vue code, and the reverse.

### Who maintains it?

Orshot, the API for automated image, PDF and video generation. Colorshot is the picker inside the Orshot template editor.