v1.0.0
Interactive Demo

Word clouds that feel native to D3

Type words below, tune the layout in real time, and watch the cloud animate its placement. Built on a persistent bitmap board with incremental streaming, promise-friendly async, and full D3 selection rendering.

ESM-first Incremental streaming Async / await Bitmap collision D3 selection rendering
Words Placed
0
in the cloud
Footprint
layout bounds
Largest Word
0px
font size
Coverage
0%
of canvas area
Word Manager
Weight controls font size (1–200). Press Enter to add.
Quick presets
Active preset drives the Stream Lab and Spiral Comparison.
Words (0)
Add words above to get started
Live word cloud
Add words on the left to see the cloud
Add words to see the cloud
Layout
Spiral
Rotation Mixed
Padding 3
Typography
Min size 14px
Max size 80px
Font
Color Palette
Scheme
Custom colors
Feature
Incremental Streaming Lab
Words arrive one burst at a time. Existing words never move — new placements integrate into the live board.
Stream board
Idle — inject a burst or start auto stream
0 words
Total placed
0
Last burst
0
Board bounds
Recent arrivals ≈0 words/s
No arrivals yet
How it works

Each addAsync(batch) call places a new batch into the same persistent bitmap board.


Existing words are never disturbed — the algorithm only searches free space beyond the current boundary for incoming words.

Feature
Spiral Comparison
Same data, same seed — only the search geometry differs. Archimedean is smoother; Rectangular has sharper steps.
Archimedean Spiral
Smooth radial search · balanced packing
0 words
Rectangular Spiral
Axial steps · tighter rectangular packing
0 words
Feature
Minimal update — add duplicate or remove
Adding a word that already exists boosts its weight and triggers a fresh placement pass. The transitions keep that update readable, but the cloud may re-pack around the changed word.
Try it

Click a word chip to add it again (+20 weight). Click any word in the cloud to remove it.

Add duplicates
Event log
Weight demo cloud
Click chips to boost weight · click words in cloud to remove
0 words
API & Features
Three lines to a cloud.
The library surface is intentionally small. Everything you need, nothing you don't.
import { cloud, renderWords } from "d3-wordcloud";
import * as d3 from "d3";

// Build the layout
const layout = cloud()
  .size([960, 560])
  .words(words)
  .fontSize((d) => scale(d.value))
  .padding(3)
  .spiral("archimedean");

// Await the result
const { words, bounds } = await layout.startAsync();

// Render with D3
renderWords(svg, words, {
  width, height,
  fill: (d) => color(d.group),
  title: (d) => `${d.text}: ${d.value}`,
});

// Incremental streaming — board persists!
await layout.addAsync(newBatch);
Bitmap collision
Pixel-perfect placement using Jonathan Feinberg's bitmask algorithm. No overlapping words, ever.
📡
Incremental add
addAsync() extends the live board. Existing words never shift or re-render.
🔄
Promise API
startAsync() and addAsync() return promises — works naturally with async/await.
🎨
renderWords()
Drop-in D3 data join helper. Bring your own colors, fonts, classes, and transitions.
🌀
Dual spirals
Archimedean for radial smoothness, Rectangular for tighter axis-aligned fills.
📦
ESM-first
Tree-shakeable ES module with a UMD fallback. Zero runtime dependencies beyond d3-dispatch.