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

sketchy-ui

v0.1.0

Published

A lightweight React component that wraps your content with a hand-drawn sketchy SVG border

Readme

sketchy-ui

A lightweight React component that wraps your content with a hand-drawn SVG border. Perfect for adding a sketchy, playful aesthetic to your UI elements.

Features

  • 🎨 Randomly generated hand-drawn SVG borders
  • 🎯 Lightweight with zero dependencies (except React)
  • ⚡️ High performance - SVG generated once on mount
  • 🎭 Smooth hover fill effects with CSS
  • 🔧 Fully customizable (colors, stroke width, seed)
  • 📦 TypeScript support included
  • 🌲 Tree-shakeable ESM/CJS builds
  • ♿️ Fully accessible - preserves interactivity and screen reader compatibility

Installation

npm install sketchy-ui

or

yarn add sketchy-ui

Usage

import { Sketch } from 'sketchy-ui';

function App() {
  return (
    <Sketch
      color="#333"
      strokeWidth={2}
      roughness="medium"
      hoverFillColor="rgba(255, 200, 0, 0.1)"
    >
      <p>Your content here</p>
    </Sketch>
  );
}

API

Props

| Prop | Type | Default | Description | | ---------------- | ------------------------------- | --------------- | ------------------------------------------------------------------ | | children | ReactNode | required | Content to wrap with hand-drawn border | | color | string | '#000000' | Color of the sketch border | | strokeWidth | number | 2 | Width of the border stroke | | roughness | 'light' \| 'medium' \| 'hard' | 'medium' | Roughness level: light (subtle), medium (moderate), hard (sketchy) | | hoverFillColor | string | 'transparent' | Fill color when hovering | | seed | number | undefined | Seed for random generation (use same seed for consistent border) | | className | string | undefined | Additional CSS class name | | style | React.CSSProperties | undefined | Additional inline styles |

Examples

Basic Usage

<Sketch>
  <button>Click me!</button>
</Sketch>

With Hover Effect

<Sketch color="#ff6b6b" hoverFillColor="rgba(255, 107, 107, 0.1)">
  <div>Hover over me!</div>
</Sketch>

Different Roughness Levels

{
  /* Light: subtle wobble, clean look */
}
<Sketch roughness="light" color="#333">
  <p>Light sketchy border</p>
</Sketch>;

{
  /* Medium: moderate wobble (default) */
}
<Sketch roughness="medium" color="#333">
  <p>Medium sketchy border</p>
</Sketch>;

{
  /* Hard: very sketchy appearance */
}
<Sketch roughness="hard" color="#333">
  <p>Hard sketchy border</p>
</Sketch>;

Consistent Border (Using Seed)

<Sketch seed={12345} roughness="medium">
  <p>This border will always look the same</p>
</Sketch>

SketchProvider

Use SketchProvider to set default sketch configuration for multiple components:

import { SketchProvider, useSketch, Sketch } from 'sketchy-ui';

function MyCard() {
  const sketchConfig = useSketch();

  return (
    <Sketch {...sketchConfig}>
      <div>This uses the provider's configuration</div>
    </Sketch>
  );
}

function App() {
  return (
    <SketchProvider roughness="medium" color="#333" strokeWidth={2}>
      <MyCard />
      <MyCard />
      {/* All cards will use the same sketch config */}
    </SketchProvider>
  );
}

useSketch Hook

The useSketch() hook returns the current sketch configuration from the nearest SketchProvider:

const sketchConfig = useSketch();
// Returns: { roughness, color, strokeWidth, hoverFillColor, enabled }

Accessibility

The Sketch component is designed to be fully accessible and preserve all interactivity:

  • ✅ Click-through: SVG overlay uses pointerEvents: 'none' so all clicks, touches, and interactions pass through to wrapped elements
  • ✅ Keyboard navigation: Focus states and keyboard events work normally on wrapped elements
  • ✅ Screen readers: SVG is marked with aria-hidden="true" since it's purely decorative
  • ✅ Form controls: Buttons, inputs, and other interactive elements maintain full functionality
  • ✅ Z-index management: Content is properly layered to ensure visibility and interactivity

Example with fully functional button:

<Sketch color="#333" roughness="medium">
  <button onClick={handleClick} aria-label="Submit form">
    Submit
  </button>
</Sketch>;
{
  /* Button remains fully clickable, keyboard accessible, and screen reader compatible */
}

How It Works

The Sketch component uses multi-stroke rendering (inspired by Excalidraw) to create an authentic hand-drawn appearance:

  • Multiple overlapping paths: Each component renders 2-3 slightly different paths
  • Layered opacity: Strokes are layered with varying opacities for depth
  • Per-level configuration: Each roughness level has tuned settings for strokes, offsets, and point density
  • Control point randomness: Higher roughness levels have more organic variation in curve control points
  • Lightweight & fast: SVG generation happens once on mount, with no runtime performance impact

Development

# Install dependencies
npm install

# Build the package
npm run build

# Watch mode for development
npm run dev

# Lint code
npm run lint

# Format code
npm run format

Testing Locally

The package includes a demo project in the examples/ directory. To test your component:

# Build the package
npm run build

# Navigate to the demo
cd examples/demo

# Install dependencies
npm install

# Run the demo
npm run dev

The demo will be available at http://localhost:3000 and showcases various use cases of the component.

Publishing

# Build and publish to npm
npm run prepublishOnly
npm publish --access public

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.