toonstrip v0.1.6 · MIT · Astro integration

Comic strips from data, drawn live on your page.

Write panels, characters, and lines as JSON. toonstrip renders them on real canvases that reflow with the page and read aloud to screen readers. No image exports to keep in sync.

Open the playgroundRead the docs

1100 px

Drag the slider. The strip is not an image: each panel is a canvas, and the column count comes from the container width. Edit this strip in the playground →

30-second install

Three steps, one strip.

Install two packages, register the integration, drop the component in a page. The panel on the right is exactly what the snippet renders.

terminal
pnpm add @toonstrip/astro @toonstrip/pack-comic-chat
astro.config.mjs
// astro.config.mjs
import { defineConfig } from "astro/config";
import { toonstrip } from "@toonstrip/astro";

export default defineConfig({
  integrations: [toonstrip({ packs: ["@toonstrip/pack-comic-chat"] })],
});
src/pages/index.astro
---
import { ComicStrip } from "@toonstrip/astro";
---
<ComicStrip
  document={{
    version: 1,
    panels: [{
      backdrop: "field",
      bodies: [{ character: "dan", emotion: { angle: 0, intensity: 0.8 }, pose: "wave" }],
      speakers: [{ speaker: "dan", balloon: "speech", text: "Hello from toonstrip!" }],
    }],
  }}
  packs={["comic-chat"]}
  client:visible
/>

Result

How it works

You write data. A pack supplies the art. It renders live.

{ "backdrop": "field",
  "camera": "medium",
  "bodies": [{ "character": "dan",
               "emotion": { "angle": 0, "intensity": 0.8 } }],
  "speakers": [{ "speaker": "dan", "balloon": "speech",
                 "text": "Hello!" }] }

You write data

A Comic Strip Document: panels, who is on stage, what they feel, what they say. Plain JSON with a published schema. No TypeScript required to produce it.

A pack supplies the art

Characters, poses, expressions, and backdrops come from an asset pack. Fifteen characters and three backdrops ship by default; add your own with a sprite sheet and a JSON manifest.

canvasdevicePixelRatioResizeObserverrole="img"

It renders live

Each panel is its own canvas, sharp at any zoom, re-laid out when the container resizes, and described to assistive tech from the dialogue itself.

Use cases

Where a strip beats a paragraph.

Every strip below is hand-written JSON, rendered live. Open any of them in the playground.

TL;DR at the top of a long post

Three panels that say what four thousand words say. The post stays; the strip is the summary.

Open in playground →

Tutorials and FAQs as dialogue

A question and an answer read faster with two faces than with a definition list.

Open in playground →

Release notes

What changed, what you have to do, in two panels. This one is a real toonstrip release.

Open in playground →

Objection and answer

The reader's doubt, voiced by a character, then answered. Over-the-shoulder and reaction shots do the work.

Open in playground →

Replaying a conversation

A chat thread or interview excerpt, with the room title as the channel name. Lines map straight to balloons.

Open in playground →

Data from anywhere

The document is JSON. Write it by hand, generate it from a script, store it in a CMS field, or have an LLM you call yourself produce it. toonstrip only renders.

Open in playground →

Asset packs

Bring your own characters.

The default pack is the original Microsoft Comic Chat roster, redistributed under MIT. The second pack is one original character and one backdrop: the smallest proof that the pack contract is not tied to the default art.

comic-chat · 15 characters · 3 backdrops

dan
anna
bolo
denise
kevin
lynnea
margaret
rebecca
tiki
sage
kwensa
hugh
maynard
scotty
tongtyed

example · 1 character · 1 backdrop

pip

How to add a character

Why not an image?

What a live canvas gives you that a PNG can't.

PropertyPre-rendered PNGExported SVGtoonstrip
Reflows to the containerNo. One fixed layout.Scales, doesn't reflow.Column count follows width.
Sharp on any displayOnly at export size.Yes.Yes, DPR-aware backing store.
Screen readersOne alt text, if you wrote it.Depends on the export.Every panel described from its own lines.
Change one line of dialogueRe-render, re-upload.Re-export.Edit the JSON.
Page weight for a 3-panel stripOne large image.Text-heavy vector.Only the sprites it references.