Skip to content

Getting started

Choose the package at the layer where your interface needs hand-drawn expression.

Requirements

  • A modern JavaScript runtime and package manager
  • A browser when using Canvas, SVG surfaces, or DOM annotations
  • TypeScript is optional; every published package includes type declarations

Draw with Rough.js

Install the renderer:

sh
pnpm add @rougher-stuff/roughjs

Create a Canvas surface and draw a deterministic rounded shape:

ts
import rough from '@rougher-stuff/roughjs';

const canvas = document.querySelector('canvas')!;
const drawing = rough.canvas(canvas);

drawing.roundedRectangle(20, 20, 220, 120, {
  cornerRadius: 18,
  fill: '#f0c84b',
  fillStyle: 'hachure',
  seed: 42,
});

Use rough.svg(svg) when you need SVG nodes instead of Canvas output.

Route an arrow

sh
pnpm add @rougher-stuff/perfect-arrows
ts
import { createArrow, toSvgPath } from '@rougher-stuff/perfect-arrows';

const arrow = createArrow({
  from: { x: 20, y: 40 },
  to: { x: 240, y: 160 },
  route: { type: 'swoop', bend: 0.4 },
  end: { type: 'open-arrow', size: 12 },
});

const pathData = toSvgPath(arrow.body);

The package returns geometry rather than mounting DOM, so the same route works with SVG, Canvas, or a custom renderer.

Annotate an interface

Rough Notation uses Rough.js as a peer dependency:

sh
pnpm add @rougher-stuff/rough-notation @rougher-stuff/roughjs
ts
import { annotate } from '@rougher-stuff/rough-notation';

const target = document.querySelector('#important')!;
const annotation = annotate(target, {
  type: 'highlight',
  color: '#f0c84b',
  seed: 42,
});

annotation.show();

Continue with the architecture guide to see how these layers compose, or open a package guide for focused APIs.

Released under the MIT License.