Ribbit
Turn any seed into deterministic generative art on a canvas. One string in, the same mark out, every time. Zero dependencies, with React and Svelte adapters.
A user id, a commit hash, a username: anything that is a string can be a picture. Ribbit hashes the seed into a uint32, runs it through a deterministic field, and paints one of six patterns on a canvas. Same seed, same pixels, on any machine, forever. No network, no state, no runtime dependencies.
The obvious use is avatars you do not have to store. The less obvious one is OG images, placeholder art, and per-entity marks in a dashboard.
One seed, six patterns. Hover any of them: the cells light up around the cursor, and the mark at rest is exactly what the static export gives you.
Using it#
npm i ribbit-canvasimport { render, toDataURL } from "ribbit-canvas";
render(canvas, "null-frog", { pattern: "dither", palette: "moss" });
const png = toDataURL("null-frog", { preset: "avatar" });import { RibbitAvatar } from "ribbit-canvas/react";
<RibbitAvatar seed={user.id} size={40} />;The Svelte adapter is the same component under ribbit-canvas/svelte. Both pause when offscreen and respect prefers-reduced-motion.
What is in the box#
| Piece | What it does |
|---|---|
render(target, seed, options) | Paints to a canvas or a 2D context |
toDataURL / toBlob | PNG export, with og and avatar presets |
toSVG | Standalone SVG string, no canvas needed |
toWebM | Records the animated variant |
renderReactive | The mark responds to the cursor |
field(seed) | The raw deterministic field, if you want to paint it yourself |
Six patterns (dither, glyph, pulse, maze, bars, wave), four palettes (moss, tide, ember, mono) each with a light variant. A palette is just { background, ramp }, so bringing your own is a literal.
Shape of the repo#
Monorepo: packages/ribbit is the published package, apps/site is the docs plus an interactive playground where you type a seed and watch it resolve. Bun for the toolchain, Biome for lint and format, MIT.
It runs on this site#
Every social card on sn4pe.com is one of these. toSVG needs no canvas, so it runs on the server: each page seeds a field from its own title, and that field is the backdrop the card is composed over. No stored images, no asset pipeline, and two posts can never collide.