<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thomas Budin</title>
    <description>The latest articles on DEV Community by Thomas Budin (@thomasbudin).</description>
    <link>https://dev.to/thomasbudin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4212108%2F328621c1-e53c-4d52-a9a8-70fd8ac2f3fa.png</url>
      <title>DEV Community: Thomas Budin</title>
      <link>https://dev.to/thomasbudin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thomasbudin"/>
    <language>en</language>
    <item>
      <title>I kept buying notebooks, so I built Papertooth instead</title>
      <dc:creator>Thomas Budin</dc:creator>
      <pubDate>Mon, 02 Nov 2026 13:00:05 +0000</pubDate>
      <link>https://dev.to/thomasbudin/i-kept-buying-notebooks-so-i-built-papertooth-instead-1l30</link>
      <guid>https://dev.to/thomasbudin/i-kept-buying-notebooks-so-i-built-papertooth-instead-1l30</guid>
      <description>&lt;p&gt;I have a notebook problem.&lt;/p&gt;

&lt;p&gt;I have an unreasonable number of notebooks because I like the idea of writing things down.&lt;/p&gt;

&lt;p&gt;Naturally, I am reluctant to write in any of them. A clean notebook contains limitless possibilities. Writing on the first page would force it to become an actual notebook, which seems unnecessarily risky.&lt;/p&gt;

&lt;p&gt;So I keep buying more.&lt;/p&gt;

&lt;p&gt;Eventually, I decided to bring some of what I like about notebooks to the browser instead.&lt;/p&gt;

&lt;p&gt;That became Papertooth, a free and open-source library for giving web interfaces an imperfect, drawn-on-paper feeling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Papertooth?
&lt;/h2&gt;

&lt;p&gt;Paper-makers call the fine grain on a sheet its tooth. It is what grips the pencil and what you feel beneath your fingers.&lt;/p&gt;

&lt;p&gt;Papertooth is a collection of web components and styles inspired by paper, handwriting and Japanese stationery.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dotted, lined, grid and graph paper- highlighter marks- hand-drawn circles, boxes and underlines- rubber stamps and picture stamps- sticky notes and washi tape- calendars and planner pieces- handwritten forms and to-do lists- photo frames and print effects- hand-drawn diagrams
The CSS works on its own. An optional JavaScript module adds ink textures, responsive hand-drawn shapes, grid alignment and draw-on animations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also React components for the elements that benefit from a React API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Papertooth
&lt;/h2&gt;

&lt;p&gt;Install the package from npm:&lt;/p&gt;

&lt;p&gt;npm install papertooth&lt;/p&gt;

&lt;p&gt;Import the styles and initialise the drawing behaviour:&lt;/p&gt;

&lt;p&gt;import 'papertooth/css';&lt;/p&gt;

&lt;p&gt;import { init } from 'papertooth';&lt;/p&gt;

&lt;p&gt;const kit = init({ pen: 'ink-ai', motion: 'scroll' });&lt;/p&gt;

&lt;p&gt;Papertooth can also be used directly from a CDN if you do not have a build step.&lt;/p&gt;

&lt;p&gt;The module does nothing when it is imported, so it is safe to import during server rendering. Call init() in the browser. With React or Next.js, use papertooth/react. TypeScript types are included.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding some paper to a page
&lt;/h2&gt;

&lt;p&gt;Papertooth mostly uses classes and data attributes, so ordinary HTML can become part of the paper interface.&lt;/p&gt;

&lt;p&gt;Add the pt-desk class to the body and a pt-sheet with cream paper and dot ruling. Inside it, use pt-wobble on a heading, pt-mark on highlighted text, pt-link on a link, pt-btn on a button and pt-sticky for a note.&lt;/p&gt;

&lt;p&gt;The result still uses real HTML elements. The button remains a button, the link remains a link and the text remains text.&lt;/p&gt;

&lt;p&gt;Papertooth adds the visual treatment around them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using it with React
&lt;/h2&gt;

&lt;p&gt;Papertooth includes React components for buttons, marks, annotations, planner pieces and form controls.&lt;/p&gt;

&lt;p&gt;Import Btn, Mark, Anno, Wobble and Check from papertooth/react.&lt;/p&gt;

&lt;p&gt;Elements such as sticky notes, tape and stamps remain ordinary markup, so a React-specific wrapper is not required for everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picture stamps
&lt;/h2&gt;

&lt;p&gt;The library currently includes 18 picture-stamp illustrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;frog- bear- tiger- rabbit- tanuki- owl- cat- paw- daruma- Mount Fuji- cherry blossom- onigiri- cloud- sun- tick- star- heart- arrow
A picture stamp can be added with the pt-stamp class, a data-pic value such as frog, a data-ink colour and an accessible label.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each illustration is also available as an individual SVG file in the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only load what you use
&lt;/h2&gt;

&lt;p&gt;The complete stylesheet is about 20 KB gzipped, but Papertooth can also be imported in smaller parts.&lt;/p&gt;

&lt;p&gt;Start with papertooth/css/base, then import only the parts a page uses, such as papertooth/css/highlight, papertooth/css/marks or papertooth/css/goods.&lt;/p&gt;

&lt;p&gt;Separate stylesheets are available for forms, planner pieces, images, diagrams and the other component groups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interaction and accessibility
&lt;/h2&gt;

&lt;p&gt;The hand-drawn treatment should not replace the behaviour people expect from an interface.&lt;/p&gt;

&lt;p&gt;Papertooth accounts for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pointer hover- pressed states- keyboard focus- selected and expanded states- disabled controls- visited links- reduced-motion preferences- forced-colour and high-contrast modes
Visitors who prefer reduced motion see the completed marks without the drawing animation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The library also uses real controls underneath its drawn checkboxes, radio buttons and form elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Imperfection without randomness
&lt;/h2&gt;

&lt;p&gt;A hand-drawn interface needs variation, but it should not change unpredictably every time the page renders.&lt;/p&gt;

&lt;p&gt;Papertooth uses seeded shapes. The same seed produces the same line, circle or outline, including during server rendering and hydration.&lt;/p&gt;

&lt;p&gt;You can give an element a fixed data-seed when you want its shape to remain consistent.&lt;/p&gt;

&lt;p&gt;This keeps the result imperfect without making the layout feel unstable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Papertooth is free and open source.&lt;/p&gt;

&lt;p&gt;You can explore the components and interactive examples here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tbudin.github.io/papertooth" rel="noopener noreferrer"&gt;https://tbudin.github.io/papertooth&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The package is available on npm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/papertooth" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/papertooth&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built it because I wanted some of the character of paper without having to make a mark in one of the notebooks I am apparently preserving for a future museum.&lt;/p&gt;

&lt;p&gt;What should I add to Papertooth next?&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
