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

drawesome

v0.1.1

Published

A drawing toolbar for React. Seven pens, an eraser, SVG and PNG export, no dependencies.

Downloads

2,314

Readme

npm version downloads

Drawesome is a drawing toolbar for React. Seven pens that behave like pens, an eraser that takes away area rather than whole strokes, and SVG or PNG out. No dependencies beyond React.

Install

npm install drawesome

Peer dependency: react >=18.

Quick Start

import { Draw } from 'drawesome'
import 'drawesome/styles.css'

function Canvas() {
  return (
    <div style={{ height: 480 }}>
      <Draw />
    </div>
  )
}

It fills its parent container. Set a height on the wrapper.

The tools

Each behaves like the thing it's named after. The pencil, pen and brush thin out the faster you move; the fineliner and highlighter hold one width whatever you do. The fountain pen goes by direction instead: thick one way, hairline the other. No two strokes come out quite the same.

The eraser takes away area rather than whole strokes, so you can rub out part of a line and keep the rest.

Props

Surface

| Prop | Type | Default | Description | |------|------|---------|-------------| | board | { w, h } | element size | Fixed drawing area. Omit and it matches the element | | background | string | "#ffffff" | Any CSS colour, "transparent" to paint nothing, or "checker" | | initialStrokes | Stroke[] | [] | Strokes to open with | | onChange | (strokes) => void | | Fires on every finished stroke and every erase | | className | string | | Passed to the root element, along with style | | style | CSSProperties | | |

Tools

| Prop | Type | Default | Description | |------|------|---------|-------------| | tools | PenId[] | all seven | Which pens appear, and in what order | | eraser | boolean | true | Whether the eraser is offered | | ink | "auto" \| "shared" \| "per-tool" | "auto" | Whether a colour applies to every tool or only the one in hand | | swatches | string[] | 18 built-in | Your own palette, clamped to what the bar holds | | look | "classic" \| "studio" | "classic" | Tools shaded flat, or lit as objects | | gauge | boolean | false | Print the current size on the barrel |

Chrome

| Prop | Type | Default | Description | |------|------|---------|-------------| | chrome | boolean | true | false leaves the surface and no toolbar | | placement | "bottom" \| "left" \| "right" | "bottom" | Which edge the bar sits on | | inset | number \| string | 20 | How far off that edge | | align | "start" \| "center" \| "end" | "center" | Where along it | | draggable | boolean | false | Let people move the bar themselves | | settings | "bar" \| "tool" | "bar" | Where size and opacity live | | controls | { color, size, opacity, undo, clear, custom, minimize } | all true | Which built-in controls to show. custom is the swatch that opens the hex field and spectrum | | depth | "flat" \| "soft" \| "regular" \| "strong" | "regular" | How physical the bar looks | | theme | "light" \| "dark" \| "auto" | "light" | "auto" follows the reader's system | | tooltips | boolean \| TooltipOptions | true | Hover labels | | shortcuts | boolean | true | Single-key shortcuts | | startMinimized | boolean | false | Start collapsed | | drawWhenMinimized | boolean | false | Keep the canvas live while the bar is a disc |

Ref handle

| Method | Type | Description | |--------|------|-------------| | toSvg | () => string | Exactly what's on screen, erasing and all | | toPng | (scale?) => Promise<Blob> | scale multiplies the resolution | | download | (name?, format?, scale?) => Promise<void> | Save straight to a file | | getStrokes | () => Stroke[] | | | setStrokes | (strokes) => void | Replaces the drawing, and its undo history | | undo / redo / clear | () => void | | | getSize | () => Board | The size the drawing is being made at |

Making it yours

It's opinionated on purpose: the defaults are meant to be the version you ship. Everything here is turning things off or moving them around, not rebuilding it. If you'd rather assemble a drawing tool from parts, tldraw or Excalidraw will suit you better.

Pick the tools and their order, and switch off what you don't want:

<Draw
  tools={['pencil', 'marker', 'highlighter']}
  controls={{ undo: false, clear: false }}
/>

Set background to transparent and it paints nothing, so whatever is behind becomes the canvas:

<div className="your-paper">
  <Draw background="transparent" />
</div>

The bar is as wide as what's in it, and a phone has more height than width. On a small screen, stand it up and drop a few tools:

<Draw
  placement={narrow ? 'left' : 'bottom'}
  tools={narrow ? ['pencil', 'pen', 'marker', 'highlighter', 'brush'] : undefined}
  controls={narrow ? { undo: false, clear: false, opacity: false, custom: false } : undefined}
/>

Getting the drawing out

const draw = useRef<DrawHandle>(null)

<Draw ref={draw} />

await draw.current.download('sketch', 'png', 2)

Strokes are plain data: store what onChange gives you and hand it back as initialStrokes.

Pieces

chrome={false} leaves you the surface with no toolbar. DrawSurface, Toolbar and useDrawing are exported separately if you'd rather lay them out yourself, and strokePath draws a stroke anywhere you can put an SVG path. The logo above is one.

Keyboard

Every pen has a single-key shortcut, shown in its tooltip. E for the eraser, [ and ] for size, ⌘Z and ⇧⌘Z for undo and redo. Hold Shift while drawing to lock the stroke to the nearest of eight directions.

License

© 2026 Benji Taylor

Licensed under MIT