Many text utilities are simple enough to run entirely in the browser.

A sentence counter is a good example. The browser already has everything it needs to accept text, analyze it, and display useful statistics. Sending the input to a remote server is often unnecessary.

I built a small browser-based sentence counter as part of TextFixHub, a collection of free text utilities for everyday writing and editing.

You can try it here:

TextFixHub Sentence Counter

Why process text locally?

Text input can be sensitive. It may contain:

  • Draft articles
  • School assignments
  • Internal notes
  • Customer messages
  • Code comments
  • Unpublished content

For a basic counting tool, uploading this text to a server does not provide much additional value. Local processing has several useful properties:

  • The input does not need to leave the user's device.
  • There is no text-processing API to maintain.
  • The tool can respond without waiting for a network request.
  • The application can work without a user account.
  • The server does not need to store or process the submitted text.

This does not make every browser application private by default. Analytics, third-party scripts, error reporting, and hosting configuration still matter. It simply means that the core text analysis can remain local.

What the tool calculates

The sentence counter displays more than just a sentence total. It also calculates:

  • Sentence count
  • Word count
  • Character count with spaces
  • Character count without spaces
  • Paragraph count
  • Line count
  • Average sentence length
  • Average word length
  • Estimated reading time
  • Estimated speaking time

The additional statistics make the tool useful for editing and reviewing content, rather than only answering “How many sentences are there?”

A simple analysis pipeline

The browser-side pipeline is intentionally straightforward:

  1. Read the current value from the text input.
  2. Normalize the relevant whitespace.
  3. Detect sentence boundaries.
  4. Split the text into words, paragraphs, and lines.
  5. Calculate the derived statistics.
  6. Render the results immediately.

The important design choice is that the input stays in the browser throughout this process.

A simplified version of the idea looks like this:

type TextStats = {
  sentences: number
  words: number
  characters: number
  charactersWithoutSpaces: number
  paragraphs: number
  lines: number
}

function countWords(text: string): number {
  const normalized = text.trim()

  if (!normalized) {
    return 0
  }

  return normalized.split(/\s+/).length
}

function countCharactersWithoutSpaces(text: string): number {
  return text.replace(/\s/g, '').length
}

Enter fullscreen mode Exit fullscreen mode

The actual implementation also needs to handle empty input, whitespace-only input, paragraph boundaries, and the distinction between visible characters and whitespace.

Sentence boundaries are not completely trivial

Counting sentences looks easy until real text appears.

A simple approach can count punctuation such as ., !, and ?. However, periods can also appear in:

  • Abbreviations
  • Decimal numbers
  • Domain names
  • Email addresses
  • Version numbers
  • Initials

This means that a sentence counter should not imply perfect linguistic understanding. It is a practical text utility with defined heuristics.

For a lightweight browser tool, a transparent heuristic is often more useful than a large natural-language-processing dependency. The tool should also explain what it counts and avoid presenting an approximate result as a scientific linguistic measurement.

Reading time and speaking time

Reading and speaking time are estimates based on word count.

For example, the application can use separate words-per-minute assumptions:

const READING_WORDS_PER_MINUTE = 200
const SPEAKING_WORDS_PER_MINUTE = 130

const readingMinutes =
  wordCount / READING_WORDS_PER_MINUTE

const speakingMinutes =
  wordCount / SPEAKING_WORDS_PER_MINUTE

Enter fullscreen mode Exit fullscreen mode

These numbers are not universal facts about every reader or speaker. They are simple reference estimates that help users understand the approximate size of their text.

The interface should avoid suggesting false precision. Displaying “about 2 minutes” is generally more useful than displaying a value with several decimal places.

Why I used a static deployment

The application is built with Next.js and TypeScript and deployed as a static website.

The tool does not need a database or an application server to analyze text. This keeps the architecture small:

  • The UI runs in the browser.
  • The text-processing functions are regular TypeScript modules.
  • The page can be statically generated.
  • The deployment surface is smaller than a server-based implementation.

A smaller architecture also makes the privacy explanation easier to verify: the main text operation is visible in the client-side application rather than hidden behind an API.

Testing the text-processing functions

The UI is only one part of the tool. The text-processing functions should be tested independently with cases such as:

  • Empty input
  • Whitespace-only input
  • One sentence
  • Multiple paragraphs
  • Multiple line breaks
  • Punctuation at the end of a sentence
  • Text containing numbers
  • Text containing Unicode characters
  • Text with repeated spaces

Separating the counting logic from the UI makes these cases easier to test and reduces the chance that a visual change breaks the underlying calculations.

What I learned

The main lesson was that small tools still need clear boundaries.

A sentence counter does not need an account system, a database, or a text-processing API. It does need:

  • A clearly defined counting method
  • Useful output beyond one number
  • Reasonable handling of empty and unusual input
  • Tests for the core functions
  • A clear explanation of what happens to user text

Local-first processing is not a complete privacy guarantee for an entire website. It is a practical architectural decision for the core task: the text entered into the tool does not need to be uploaded for the tool to work.

The finished tool is available here:

Try the TextFixHub Sentence Counter

The other TextFixHub tools are available at https://www.textfixhub.com/.