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

penora

v0.1.6

Published

<p align="center"> <img src="https://raw.githubusercontent.com/satyajitghana/penora/master/apps/web/public/logo.png" alt="penora" width="480" /> </p>

Readme


Install

npm i penora
# or
pnpm add penora
# or
yarn add penora
# or
bun add penora

shadcn registry

Install the Penora component directly into your shadcn project:

npx shadcn@latest add https://penora-ui.vercel.app/r/penora.json

This installs the penora npm package and adds components/ui/penora.tsx to your project.

Usage

import { Penora } from 'penora/react';

// Use a built-in font — no files to host
<Penora text="hello world" font="BrittanySignature" />

// Or bring your own TTF
<Penora text="hello world" fontUrl="/fonts/MyFont.ttf" />

Built-in fonts

BrittanySignature · Sacramento · IndieFlower · LeagueScript · HomemadeApple · ComingSoon · GreatVibes · Kalam · Pacifico · PinyonScript · PlaywriteAT · PlaywriteCUGuides · PlaywriteUSTradGuides · Tillana

Fonts are served via jsDelivr CDN — no self-hosting needed.

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | text | string | required | Text to animate | | font | FontName | — | Built-in font name (fetched from CDN) | | fontUrl | string | — | URL to a custom .ttf font file | | color | string | '#0f1117' | Ink color | | size | number | 84 | Base font size in px | | speed | number | 1 | Animation speed multiplier | | lineHeight | number | 1.32 | Line height multiplier | | quality | 'calm' \| 'balanced' \| 'snappy' | 'balanced' | Timing quality preset | | seed | string \| number | 0 | Deterministic randomness seed | | brushScale | number | auto | Brush width scale factor | | profile | PenoraProfile | auto | Advanced brush/duration settings | | animate | boolean | true | Whether to animate or render static | | incremental | boolean | true | Append-aware streaming (typing) mode | | autoReplay | boolean | false | Loop the animation | | playheadKey | number | 0 | Increment to replay from the start |

What makes penora different

penora enhances the base handwriting animation engine with realistic pen stroke physics:

  • Pressure tapering — the stroke starts thin (nib touches paper), swells to full width, then tapers off (nib lifts). Replicates the feel of a real pen.
  • Seeded width jitter — per-segment width variation (±18%) driven by a deterministic seed, so every character has a unique but reproducible pressure profile.
  • Micro-wobble — a tiny seeded perpendicular displacement on each polyline point creates the organic imperfection of a human hand — no two strokes look mechanical.

How it works

Font (.ttf) → Glyph parsing (typr.js) → Contour extraction → Polyline segments
    → Timing model (path length + complexity + cadence jitter)
        → Canvas rendering (pressure taper + width jitter + wobble + eased ink progression)
  1. Font parsing — font files are parsed at the glyph level, extracting bezier curves and contour data via typr.js
  2. Contour extraction — each character's outlines are decomposed into drawable polyline segments, sorted left-to-right
  3. Timing model — per-character duration is computed from path length, complexity, and seeded cadence jitter
  4. Canvas rendering — segments are drawn progressively with smoothstep easing, clipped to the glyph's fill path, with pressure taper and jitter applied per segment

Core exports

import {
  QUALITY_PRESETS,
  clamp,
  computeCatchupMultiplier,
  getQualityPreset,
  hashSeed,
  isTypingBurst,
  seededRandom,
  segmentGraphemes,
} from 'penora';

import { Penora, FONTS } from 'penora/react';
import type { PenoraProps, PenoraProfile, FontName } from 'penora/react';

Links

Credits

Original animation concept by Cristian Cretu · Inspiration from Lochie Axon