[JS] Count Word Frequency Live as You Type (No Libraries)

[JS] Count Word Frequency Live as You Type (No Libraries)

[JS] Count Word Frequency Live as You Type (No Libraries)

 

Building small utility tools in pure JavaScript is a great way to reinforce your understanding of browser APIs, DOM manipulation, and basic algorithms. In this post, you’ll learn how to build a live word frequency counter using vanilla JavaScript—no external libraries required.

The tool will monitor user input in a textarea and dynamically display a list of words and their frequencies, updating on each keystroke. We’ll explore basic string parsing, performance strategies, and best practices for building interactive JS features.

1. Setting Up the HTML Skeleton

We’ll begin with a simple HTML structure containing a <textarea> for user input and a <div> to display word frequency statistics.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Live Word Frequency Counter</title>
  <style>
    textarea {
      width: 100%;
      height: 150px;
      padding: 10px;
      font-size: 14px;
    }
    .word-frequency {
      margin-top: 20px;
      font-family: monospace;
      white-space: pre-wrap;
    }
  </style>
</head>
<body>
  <h1>Live Word Frequency Counter</h1>
  <textarea id="inputArea" placeholder="Start typing here..."></textarea>
  <div class="word-frequency" id="output"></div>

  <script src="script.js"></script>
</body>
</html>

All logic will go in a file called script.js, keeping our HTML clean and separation of concerns intact.

2. Parsing the Text Input

The key to getting word frequency is processing the textarea content. We’ll normalize the text, split it into words, and count each one.

First, we write a function to count word frequencies:

function getWordFrequencies(text) {
  const frequencies = {};

  // Normalize text: remove punctuation and set to lowercase
  const sanitized = text.toLowerCase().replace(/[^a-z\s]/g, "");
  const words = sanitized.split(/\s+/).filter(Boolean);

  for (const word of words) {
    frequencies[word] = (frequencies[word] || 0) + 1;
  }

  return frequencies;
}

This function takes a string, removes punctuation, converts to lowercase, and splits on whitespace. Filtering with Boolean removes empty strings caused by multiple spaces.

3. Displaying the Frequency Results

Next, let’s update the DOM with live results. We’ll loop over the frequency object and build a string for display.

function updateOutput(frequencies) {
  const outputDiv = document.getElementById("output");

  const sortedWords = Object.keys(frequencies).sort((a, b) => frequencies[b] - frequencies[a]);
  const lines = sortedWords.map(word => `${word}: ${frequencies[word]}`);

  outputDiv.textContent = lines.join("\n");
}

By sorting the words by frequency descending, users can quickly see which terms they use most.

4. Live Input Handling with Event Listeners

All that’s left is to wire up our event listener so the frequency analysis happens in real-time:

document.getElementById("inputArea").addEventListener("input", (event) => {
  const inputText = event.target.value;
  const frequencies = getWordFrequencies(inputText);
  updateOutput(frequencies);
});

The input event fires on every keystroke, so we can process the text and update the display live. This is perfect for small to medium text input, typical in blogs or email drafting scenarios.

5. Optimization and Usability Tips

Although our tool works well for most use cases, here are a few best practices:

  • Debounce Input: For larger texts, debounce the handler to avoid excessive processing.
  • Case Sensitivity: We normalize to lowercase to treat “Word” and “word” as the same.
  • Regex Tweaks: Adjust the regex to include non-ASCII letters or hyphenated words.
  • Security: Avoid inserting unsanitized input into HTML (we use textContent for safety).

Here’s an example with basic debouncing to improve responsiveness:

let debounceTimer;

inputArea.addEventListener("input", (event) => {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    const text = event.target.value;
    const freqs = getWordFrequencies(text);
    updateOutput(freqs);
  }, 200); // Update every 200ms
});

This prevents rapid consecutive inputs from hammering the parsing logic.

Conclusion

We successfully built a no-library live word frequency analyzer using only vanilla JavaScript. This project is a great practical example of using event handling, string parsing, object manipulation, and DOM updates together. It’s lightweight, fast, and easy to extend.

As an enhancement challenge, you might add real-time charts, export functionality, or a UI toggle for case sensitivity. Keep tinkering—this is how JS mastery begins!

 

Useful links: