Skip to content
pedrovilaca.dev
Read this page in Portuguese

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>.

Web

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

  1. The text is drawn once on an offscreen 2D Canvas.
  2. The library reads the pixels of that drawing and creates a particle every few filled pixels. Each particle's position becomes its "target".
  3. 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, with update, pause, resume, and destroy.
  • React (text-bubbles/react): a <TextBubbles> component and a useTextBubbles hook, 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 with ResizeObserver, 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-motion is 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.