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

jayasree

v0.4.0

Published

Animated stroke-trace widget for Malayalam (or any script) - renders the JSON produced by the jayasree Python package as a left-to-right ink reveal

Downloads

610

Readme

Jayasree (JS)

Animates Malayalam text as handwriting - a pen traces each letter left to right, over a faint ghost of the complete letterform.

Self-contained. No server. No font file at runtime. Glyph shapes are pre-computed and bundled in glyph-data.json.

Install

npm install jayasree

Published at npmjs.com/package/jayasree. You can also copy js/src/ into your project or serve it locally instead - it's plain ES modules, no build step required.

Usage

import { createStrokeWriter } from "jayasree";

const writer = createStrokeWriter(document.getElementById("stage"));
await writer.load();          // fetches glyph-data.json once
await writer.loadStrokes();   // fetches stroke-data.json (no-op if absent)
await writer.play("നന്ദി");   // any Malayalam Unicode text

writer.replay();   // play the same text again
writer.cancel();   // stop mid-animation
writer.destroy();  // cancel + clear the container

Spaces and common punctuation (., ,, !, ?, ;, :, -, quotes, parens) work in play() text without any setup - they're rendered as plain static characters, not animated handwriting, since they're not part of any script's letterforms. See UNIVERSAL_CHARS in index.js for the exact set.

Chillu letters (ൺ/ൻ/ർ/ൽ/ൾ/ൿ) work in play() text regardless of which of the two valid Unicode encodings they use. A chillu can be written as one atomic codepoint ( = U+0D7B, the modern form) or as the legacy 3-codepoint sequence consonant + ് (virama) + ZWJ ( + + zero-width joiner) - both render identically in every font, including real-world text from WhatsApp, older keyboards, and many CMSs. play() normalizes the legacy form to its atomic equivalent internally, so both spellings trace the same stroke; you never need to normalize input yourself. See normalizeChillus()/LEGACY_CHILLU in index.js.

Two data files

Both live in js/ and should be committed to your repo:

| File | What it contains | Font-specific? | |---|---|---| | src/glyph-data.json | SVG outlines + advance widths for every cluster | Yes - re-run tools/build_glyph_data.py when you change fonts | | stroke-data.json | Hand-authored centerline stroke paths | No - commit once, works across fonts |

When stroke-data.json has coverage for a cluster, the pen follows those paths. Otherwise it falls back to tracing the outer contour of the font outline.

Regenerating glyph-data.json for a different font

cd python && poetry install
# defaults to the bundled Manjari-Regular.ttf:
poetry run python ../tools/build_glyph_data.py
# or supply your own:
poetry run python ../tools/build_glyph_data.py /path/to/MyFont.ttf

Authoring stroke-data.json

Open tools/stroke-recorder.html in a browser, draw strokes over each ghost glyph, and export. The output is keyed by Unicode cluster ("ന", "ക്ഷ"). Save it as js/src/stroke-data.json and commit.

Configuring per-cluster behaviour

import { createStrokeWriter, START_OVERRIDES, DIRECTION_OVERRIDES } from "jayasree";

// Where on the contour the pen starts (fallback mode only)
START_OVERRIDES["ന"] = "topmost";   // "leftmost" | "rightmost" | "topmost" | "bottommost" | 0..1 fraction
START_OVERRIDES["ക"] = ["leftmost", 0.1]; // per sub-contour array

// Which way around the contour the pen travels (fallback mode only)
DIRECTION_OVERRIDES["ന"] = "reverse";  // "forward" | "reverse"

Styling

.my-stage {
  --ms-ink-color:    #1a1a2e;   /* trace line */
  --ms-ghost-color:  #e0daf5;   /* faint letterform behind the trace */
  --ms-stylus-color: #e8b84b;   /* pen-tip dot */
}

.ms-ghost and .ms-stroke are the two CSS classes on the rendered SVG. Skip the default style.css entirely and write your own if you prefer.

License

MIT.