a ui library where everything is cut and torn paper. every mount is a fresh tear from seeded randomness. same seed, same scraps, on any machine. real HTML inputs underneath. zero dependencies.

(hover anything. it re-tears itself.)

$ npm i scraps-ui
seed lab

every tear on this page derives from that one string. type the same seed tomorrow, or on your friend's machine, and you get pixel-identical paper.

the drawer

Scissor-cut buttons

each one does what it says. go on.

Fields are real inputs

your name
paper stock

Choices

Range & progress

jaggedness
gluing… 0%

^ a divider. it is also torn paper. everything is torn paper.

Overlays

tooltip

real dialog elements underneath: esc, focus, and the backdrop come free.

Feedback & loading

drawerstate
scissorsmissing again
glue stickdrying out
washi tapeplenty
patienceseeded

Dark stock

black construction paper tears white at the core, so the fringe does the outlining for you.

contrast: fine

a torn sheet over the mat

it re-tears on every open. press esc, or:

the api
<!-- 1. include both files. that's the whole install. -->
<link rel="stylesheet" href="scraps.css">
<script src="scraps.js"></script>

<!-- 2. mark up real HTML -->
<button data-scrap="button" data-color="coral">rip it</button>
<label data-scrap="toggle"><input type="checkbox"> deckle</label>

// 3. tear
Scraps.init()
Scraps.reseed('zine-04')   // same seed, same tears
Scraps.tear(el)             // re-tear one scrap
Scraps.setProgress(el, 64)
  • data-scrap: button · chip · card · field · checkbox · radio · toggle · progress · divider · dialog · menu · tabs · accordion · table · avatar · skeleton · alert
  • data-color: white · kraft · coral · marigold · blue · ink
  • data-edge: torn | cut (each type has an opinion; override it)
  • data-seed: pin one element's tear across reseeds
  • data-rot: max crookedness, in degrees
  • data-tape: (cards) slap a strip of tape on it
  • data-boil: "false" to keep a scrap still under the cursor
  • data-fx: rip · fold · glue · shred, played on click (also Scraps.fx.rip(el))
  • data-value / data-fill: progress percent and fill color