glyphed.js documentation
Write text that draws itself.
A dependency-free ESM package for animated, hand-drawn SVG text.
Install
Choose the package manager already in your project. No separate publishing step is needed for pnpm, Yarn, or Bun.
npm install glyphed.js
pnpm add glyphed.js
yarn add glyphed.js
bun add glyphed.js
Quick start
write() renders text into an element and animates it
when it enters the viewport.
import { write } from "glyphed.js";
write("#hello", "Hello, world!");
API
write(target, text, options?)- One-call DOM rendering and scroll-triggered animation.
renderText(text, options?)- Returns the SVG HTML string without accessing the DOM.
attach(element, options?)-
Triggers each rendered word through an
IntersectionObserver. animateWriting(element)- Immediately starts the stroke animation for a word.
Set animate: false for fully drawn, static text. Set
once: false when your own render cycle should
re-trigger an observer.
Handwriting is copyable by default: invisible real text sits over
each word, so selecting and copying works like normal text. Pass
copyable: false for decorative output. Undrawn strokes
stay hidden until the pen reaches them; pass
dots: true to show each stroke's starting dot ahead of
time.
Icons
Every bundled icon is on the same 24-unit grid as the lettering. Search by name, then select an icon to copy a ready-to-use import and render call. Import individual icons to keep your bundle small.
Select an icon to copy its code.
For icons inside a sentence, pass imported icons by name. Matching
:name: shortcodes draw inline; unknown shortcodes stay
as text.
import { renderText } from "glyphed.js";
import { rocket, heart } from "glyphed.js/icons";
const markup = renderText("Ship it :rocket: with :heart:", {
icons: { rocket, heart },
});
renderIcon(icon, options?)-
SVG string. Options:
size,color,strokeWidth,roughness,seed,delay,label,animate,hover(a small motion of its own while hovered). drawIcon(target, icon, options?)- Renders into an element and draws in on scroll.
icon(name, strokes)-
Define your own from path strings or the
shapeshelpers.
Charts
Pick a chart type to see it draw and copy a complete example. Charts use direct labels, accessible SVG output, and hatching as a second cue alongside color.
annotate(target, options)-
underline,circle,box,highlight,strike,cross,bracket. Returns{ redraw, remove }. -
renderChart(options)/drawChart(target, options) -
bar,line,pie,donutwith hatched fills and handwritten labels. ChartOptions-
Set
width,height,color,colors,fill,format,title,roughness,seed,dots, andanimateas needed. renderSparkline(values, options?)- A trend line one text-line tall, for inline use.
Annotations
Add a hand-drawn mark to an element after it is in the document. The returned controller lets you redraw after content changes or remove the mark during cleanup.
import { annotate } from "glyphed.js";
const mark = annotate("#price", {
type: "circle",
color: "#c63d24",
passes: 2,
});
mark.redraw();
mark.remove();
annotate(target, options)-
Types:
underline,circle,box,highlight,strike,cross,bracket. Returns{ redraw, remove }.
React
Render into a ref after mount. Re-render when the text changes.
import { useEffect, useRef } from "react";
import { write } from "glyphed.js";
export function Handwriting({ text }) {
const ref = useRef(null);
useEffect(() => {
write(ref.current, text);
}, [text]);
return <span ref={ref} />;
}
SSR
renderText() is pure string output, so it can run
during server rendering. Call attach() after hydration
when animation is needed.
import { renderText } from "glyphed.js";
const markup = renderText("Server-rendered ink", { animate: false });
Glyphs
Coverage includes lowercase and uppercase English letters, digits,
and
. , ! ? ' - & ( ) — " ` { } [ ] * = + @ :. Unsupported
characters are skipped. To add one, create a glyph module and
register it in the glyph lookup.