Modern TypeScript port of the 1996+ Microsoft Comic Chat IRC client w/ Cloudflare Durable Objects as the network layer.
Live Demo @ comics.remsky.art
The composition rules follow the SIGGRAPH '96 Comic Chat paper by David Kurlander, Tim Skelly, and David Salesin.
Validated against traces from an instrumented C++ client of the original to accurately reproduce the original engine including:
- 31-character cast, automatic panel layout
- Emotion detection, speech balloon splines
- Avatar posing, reactive angles and camera
Note
Rooms are anonymous (no accounts); moderation is rudimentary: a content filter with escalating mutes.
Deploy usage defaults are intentionally bounded by the fixed room list, but can be extended to create-on-join. If deploying publically; add Cloudflare rate-limiting rules (demo settings described below).
Local Run
Spin up locally to test via:
git clone https://github.com/remsky/comic-chat-web
cd comic-chat-web
npm install
npm run preview:workerDeployment Details
Suggested best-effort default settings against roving bots or bad actors are listed below.
- Live rooms operate over Cloudflare Durable Object WebSockets
- Bounded, chunked message history with per-socket abuse limit
- For Cloudflare Workers Builds, use
npm run buildas the build command andnpx wrangler deployas the deploy command. - Only the rooms in the
ROOMSvar (wrangler.jsonc, or the dashboard) accept connections, bounding how many Durable Objects a public deploy can create. - Each room caps active sockets (12) and per-socket send rate.
- New joins receive the latest 50 messages and load older history in 50-message chunks. Each room retains at most 500 messages.
- For a public deployment, add a Cloudflare rate-limiting rule on
/api/*and a usage notification: worker invocations could scale with heavy automated abuse.
Testing
npm ci
npm run dev # Vite dev server at localhost:5173
npm test # both vitest projects: node + worker
npm run test:browser # Playwright desktop + mobile smoke
npm run check # biome + strict tsc over src, worker, test, and toolsnpm test runs two vitest projects, selectable with --project:
| Project | Runs in | Covers |
|---|---|---|
node (test/) |
node | Engine units and golden trace suites |
worker (test/worker/) |
workerd, via @cloudflare/vitest-pool-workers |
Durable Object behavior against real SQL storage and the live WebSocket protocol |
Worker tests get isolated storage per test and read their bindings from wrangler.jsonc. They typecheck under their own test/worker/tsconfig.json, since workers types collide with the node and DOM types the rest of the suite uses.
Trace validation
The engine is validated against JSONL traces from an instrumented C++ client, the Comic Chat trace harness:
| Trace | Validation focus |
|---|---|
smoke-01 |
Core two-speaker flow, balloon modes, emotions, and panel breaks |
balloon-01 |
Interleaved say, think, whisper, and shout balloon geometry |
edge-01 |
Single-character, punctuation-only, and repeated messages |
emotion-01 |
Shouting, laughter, greetings, smileys, pointing, and waving rules |
long-01 |
Multi-panel overflow, retries, continuation, and three-speaker ordering |
speakers-01 |
Six-speaker avatar selection, placement, flipping, and ordering |
wrap-01 |
Long text, wrap boundaries, URLs, and unbreakable words |
Art pipeline
All steps are deterministic and byte-reproducible, sourced from a sibling checkout of the Comic Chat trace harness:
npm run assets:avatars: packed per-character avatar atlases and runtime manifest inpublic/assets/avatars/from the original.avbfiles.npm run assets:backgrounds: backdrop PNGs inpublic/assets/backgrounds/from the original.bgbfiles.npm run fixtures:avatars: the test fixture.
- TimBroddin/comic-chat-macos: a macOS port of Comic Chat
- gyng/comicchat (archived): quick and dirty web client and node.js server based on Comic Chat
- codegod100/comic-chat: fork of the official Microsoft source starting a Qt6 desktop port
- comicchat/comicchat: unofficial TypeScript port from the official source; connects to IRC servers over WebSockets, no backend
- theAlexes/comic-chat-deslopped: fork of the official Microsoft source sans AI cruft; with Windows build fixes
Except for the third-party material identified below, this project is licensed under the GNU Affero General Public License v3.0 only. If you operate a modified version over a network, the AGPL requires you to offer its corresponding source to the people using it.
Microsoft-derived code and artwork retain Microsoft's MIT license and notice. See Third-Party Notices and the preserved Microsoft MIT license for details.
This is an unofficial community project and is not affiliated with or endorsed by Microsoft; based on the open-source Microsoft Comic Chat repository.


