pedro/projects/text-bubbles
text-bubbles
Open source npm library that turns text into interactive 2D Canvas particles: about 4 KB, zero dependencies, for plain JavaScript, React, or as <text-bubbles>.
Context
text-bubbles (opens in a new tab) is an open source library, published on npm, that draws text as a cloud of particles. It started as a demo script and was rewritten as a library: a framework-free core with two integrations built on top of it. The playground lives at text-bubbles.pedrovilaca.dev (opens in a new tab).
Install it with npm i text-bubbles.
How it works
- The text is drawn once on an offscreen 2D Canvas.
- The library reads the pixels of that drawing and creates a particle every few filled pixels. Each particle's position becomes its "target".
- On every frame, the particles near the pointer are pushed away; the rest ease back to their target.
The result is text that falls apart when the cursor or a finger passes over it and then pulls itself back together.
Three ways to use it
- Core (
text-bubbles):createTextBubbles(target, options), in plain JavaScript or any framework, withupdate,pause,resume, anddestroy. - React (
text-bubbles/react): a<TextBubbles>component and auseTextBubbleshook, ready for the Next.js App Router. - Custom element (
text-bubbles/element): the<text-bubbles>tag, for Astro, Vue, Svelte, or plain HTML, with no framework runtime.
Lightweight, fast, and accessible
- Small: about 4 KB compressed, zero dependencies, with size limits checked on every build.
- Light on the CPU: the loop sleeps when nothing is moving, pauses when offscreen or when the tab is hidden, and draws a single path per color.
- Sharp and responsive: scales by
devicePixelRatio, follows the container withResizeObserver, and wraps the text onto multiple lines on narrow screens. - Touch without blocking scroll: passive listeners and
touch-action: pan-y. - Theming: colors can be
var(--token)and follow theme changes. - Accessible: the real text stays in the DOM and
prefers-reduced-motionis respected. - Tested: unit tests with Vitest and in-browser tests with Playwright, running in CI on every pull request.
On this site
The name at the top of the home page is the <text-bubbles> element installed from npm. The actual <h1> sits inside the tag as accessible text, and the library's script is only downloaded after the page finishes loading, so it doesn't delay the first paint.