CLI tool
gkurt/tegaki avatar
gkurt/tegaki

Tegaki: handwriting animation without hand drawing a single path

Handwriting animation for the web. Supports any font or text.

3,123 stars121 forksTypeScriptMIT

At a glance

What is it?
A TypeScript library and CLI that turns any font into animated handwriting, with harfbuzz bundled as WASM for shaping. The interesting constraints are the CLI's SVG-only output and the plugin string you pass on the command line.
Who is it for?
Use Tegaki when the effect you want is a font drawing itself, and you can accept SVG as the artifact: a README heading, a slide title, a landing page hero. The CLI path costs nothing to try and needs no install, and the React component is three lines.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

npx tegaki writes one SVG and stops there

The command line path needs nothing installed:

bash
npx tegaki "Tegaki is awesome"

That produces a self-drawing, looping `tegaki-is-awesome.svg` named after the text you passed, ready to drop into a README, a slide or a page. The boundary of this path is worth stating plainly: the CLI emits SVG only. PNG, GIF and WebM are the studio's job, not the terminal's, so a build script that wants a raster frame has to go through the interactive studio at tegaki.ink/studio.

Two discovery commands round it out, `--help` for every option and `--list-fonts` for what ships in the box. The default mode is `loop`, which repeats forever; `once` draws a single time and `static` emits the finished artwork with no animation at all.

Six flags, and one of them takes a JSON array

The common options are ordinary: `--font` picks a face, `--size` and `--color` set the output, `--stagger` offsets the letters, and `--stroke-easing` picks the curve of each stroke.

bash
npx tegaki "Hello World" --font tangerine --mode once -o hello.svg
npx tegaki "ABC" --stagger 80% --size 140 --color "#222"
npx tegaki "مرحبا بالعالم" --font amiri --stroke-easing ease-in-out-cubic
npx tegaki "Glow" --plugins '[["glow", {"radius": 0.12, "color": "#f0a"}], "taper"]'

The last line is the one to study. `--plugins` takes a JSON array whose entries are either a plugin name on its own, as `"taper"` is, or a name paired with an options object, as `"glow"` is with a radius and a color. So the effect vocabulary is a list you can write in one flag, and adding a glow does not mean writing a plugin.

Note that `-o` renames the file, which is how you avoid the text-derived filename when a build step needs a stable path.

harfbuzz does the shaping, bundled as WASM

The reason a font becomes legible handwriting instead of disconnected glyphs is the shaping step, and Tegaki runs it with harfbuzz compiled to WebAssembly. Both entry points share it: the terminal shapes text the way the renderer does, then clips the strokes to the letter outlines the same way the studio does.

What that buys you is script correctness rather than decoration. Ligatures form, Arabic letters join, Devanagari composes, and right-to-left text lays out in the right order. The bundled font list is arranged by exactly those scripts, which is the clearest hint that the shaping was the hard part of this project.

It also explains the no-native-dependencies claim. A WASM copy of the shaper ships inside the package, so nothing has to be compiled on the host before the animation runs.

Thirteen bundled fonts, and two of a different kind

The bundled set is small and chosen for script coverage rather than volume. Four are plain Latin handwriting faces: Caveat, Italianno, Tangerine and Parisienne. After that the list widens by script: Suez One for Hebrew, Amiri for Arabic, Tillana for Devanagari, Klee One for Japanese kana and Kyōiku grade 1 and 2 kanji, Nanum Pen Script for Korean Hangul syllables and jamo, Atma for Bengali, and LXGW WenKai covering the 1000 most frequent simplified Chinese hanzi.

Two entries are not ordinary text fonts. Hershey Script is a single-line plotter font drawn in its own pen strokes, and EMS Allure is Evil Mad Scientist's stroke version of Allura, also single-line. A single-line font has no outline to fill, so what you get is closer to a pen trace than to filled lettering.

Anything outside this list needs the studio: other fonts are turned into a custom bundle there rather than dropped into the package.

One engine, seven entry points

The animation core is the same everywhere; what changes is the wrapper you import.

tsx
import { TegakiRenderer } from 'tegaki/react';   // React
import { TegakiRenderer } from 'tegaki/svelte';  // Svelte
import { TegakiRenderer } from 'tegaki/vue';     // Vue
import { TegakiRenderer } from 'tegaki/solid';   // SolidJS
astro
---
import TegakiRenderer from 'tegaki/astro';       // Astro
---
ts
import { TegakiEngine } from 'tegaki/core';      // Vanilla JS
import { registerTegakiElement } from 'tegaki/wc'; // Web Components

Two details differ from the React-first example at the top. Astro takes a default import rather than a named one, and the two lowest-level paths do not return a component at all: `TegakiEngine` is the plain JavaScript engine for vanilla use, while `registerTegakiElement` is what registers the custom element for Web Components.

A private root package over three workspaces

The repository is a bun monorepo whose root package is `@tegaki/root`, marked private and version 1.0.2, with workspaces covering `packages/*`, `examples/*` and `e2e/*`. Tooling is chosen consistently: biome for `lint`, `format` and `check`, husky wired through `prepare`, and `typecheck` driven by `tsgo` from the native TypeScript preview.

Two scripts explain how the pieces fit together. `build:examples` is a chain of nine filtered builds, one per framework example, and `test:examples` runs that chain and then the Playwright end-to-end suite plus a `remotion-still` step, so the examples are treated as the compatibility matrix rather than as decoration.

The test script itself is unusual: `bun --conditions=tegaki@dev test` runs with a custom export condition, which is how tests resolve the development build of the package instead of the published one. A `tegami` script and a `.tegami/` directory with a lockfile sit alongside it.

Three releases in two days, and ten example apps

The version history is short and recent: `[email protected]` and `[email protected]` both published on 2026-09-30, then `[email protected]` on 2026-10-01, matching the repository's last push. A one-day gap between 1.0.0 and 1.0.2 says the public API was still moving in the first week, so pin an exact version rather than a range if you care about repeatability.

The `examples/` directory is the practical part: astro, editframe, next, nuxt, remotion, solid, svelte, vanilla, vite and vue, ten applications rather than ten snippets. One of them, `editframe`, is named for nothing the README explains, so treat it as an experiment until you open it.

Outside npm there are two documented integrations, Sli.dev for markdown-driven presentations and Remotion for video generated with React, each with a worked example. The licence is MIT, and the documentation site carries Getting Started, per framework guides, font generation and an API reference.

Editorial conclusion

Use Tegaki when the effect you want is a font drawing itself, and you can accept SVG as the artifact: a README heading, a slide title, a landing page hero. The CLI path costs nothing to try and needs no install, and the React component is three lines. Walk away if you need raster or video output from a script, since the command line emits SVG only and PNG, GIF or WebM go through the interactive studio, or if your script is not covered by the bundled fonts, because a custom face means building a bundle in the studio first. Before you commit, check that your target framework has a listed entry point, confirm the bundled font covers the scripts you need, and read the stroke timing options rather than assuming the defaults suit your brand.

Frequently asked questions

How do I animate handwriting with Tegaki in React?

Install the package, import TegakiRenderer from 'tegaki' and a font from 'tegaki/fonts/...', then render your text as its children with a fontSize style. The text draws itself stroke by stroke with the timing built in.

Can the Tegaki CLI export PNG or video?

No. The command line emits SVG only, with modes loop, once and static. PNG, GIF and WebM output is handled by the interactive studio at tegaki.ink/studio instead.

Which fonts ship with Tegaki and can I add my own?

Thirteen are bundled, including Amiri for Arabic, Tillana for Devanagari, Nanum Pen Script for Korean, LXGW WenKai for the 1000 most frequent simplified Chinese hanzi, plus single-line plotter faces. Fonts outside that list are turned into a custom bundle with the interactive studio.

What does the --plugins flag in Tegaki accept?

A JSON array where each entry is a plugin name on its own, such as "taper", or a name with an options object, such as glow with a radius and a color. One flag can carry several effects at once.

Does Tegaki handle Arabic and right-to-left text?

Yes. Text is shaped with harfbuzz bundled as WASM, the same path the renderer uses, so ligatures, Arabic joining, Devanagari and right-to-left text come out correctly, and strokes are clipped to the letter outlines as the studio does.

Official sources

  1. gkurt/tegaki on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gkurt-tegaki.svg)](https://hysenlabs.com/projects/gkurt-tegaki)