Turn prose into weighted terms

Most real-world word clouds start from unstructured text — articles, survey responses, commit messages, tweets. The engine expects { text, weight } pairs, so your app tokenizes the source, counts frequencies, optionally filters stop words, then passes the top N terms to layout().

Cap the term count. Very long documents can yield thousands of unique words. Take the top 50–200 by frequency before layout — you'll get a readable cloud and faster packing. Rare terms rarely fit anyway.

Typical pipeline:

  1. Normalize — lowercase, strip punctuation, collapse whitespace.
  2. Tokenize — split on word boundaries; drop tokens shorter than 2–3 chars.
  3. Filter — remove stop words ("the", "and", …) if they dominate.
  4. Count — Map<string, number> of term → frequency.
  5. Rank — sort by count descending, slice to top maxTerms.
  6. Layout — map counts to weight and call layout(items, options).

Step by step

Step 1

Tokenize and count

tokenize.js
const STOP = new Set(["the", "and", "a", "to", "of", "in"]);

export function textToItems(raw, { maxTerms = 500, minLen = 3 } = {}) {
  const counts = new Map();
  const tokens = raw.toLowerCase().match(/[a-z0-9']+/g) ?? [];

  for (const t of tokens) {
    if (t.length < minLen || STOP.has(t)) continue;
    counts.set(t, (counts.get(t) ?? 0) + 1);
  }

  return [...counts.entries()]
    .sort((a, b) => b[1] - a[1])
    .slice(0, maxTerms)
    .map(([text, weight]) => ({ text, weight }));
}
Step 2

Re-layout when the user edits text

Debounce input events (300–500 ms) so you don't re-pack on every keystroke. Show a lightweight "laying out…" state while layout() runs — especially for longer pasted documents.

Try it yourself

Edit the sample paragraph or paste your own text. Click Generate cloud to tokenize, count, and lay out the top terms.

text → cloud

Press Esc or click Exit fullscreen to return to the demo card.

Open Fullscreen to lay out the cloud on the full viewport — useful for longer pasted documents with more unique terms.