How TextKit Pro's Tools Work Under the Hood

TextKit Pro looks simple — four tabs, some textareas, a few buttons — but each tool is built on a small piece of real logic worth understanding, especially if you're relying on the numbers it reports. Everything described here runs as plain, dependency-free JavaScript directly in your browser; nothing is sent to a server, and every function below is intentionally kept pure (no DOM access) so it can be sanity-checked outside a browser too. Here's exactly how each tool works, and where its edge cases are.

Counting words, characters, sentences, and paragraphs

Word counting works by trimming the input and matching every run of non-whitespace characters with the regular expression /\S+/g, then counting the matches. This is deliberately simple: it treats “don't,” hyphenated compounds like “well-known,” and abbreviations as single words, matching how most word processors count by default. Character counts are just as direct — total length for the “with spaces” figure, and the same string with every whitespace character stripped via /\s/g for the “without spaces” figure.

Sentence counting splits the text on runs of ., !, or ?, trims each resulting piece, and discards empty fragments — so three consecutive periods or a trailing exclamation mark don't produce phantom empty “sentences.” This method has a known limitation worth flagging: splitting on punctuation alone can't distinguish a sentence-ending period from one inside an abbreviation (“Dr. Smith”) or a decimal number (“3.14”), so abbreviation- or number-dense text reports a slightly inflated count. A fully accurate sentence boundary detector needs an abbreviation dictionary and numeric-context rules — real natural-language processing — so this tool trades a little edge-case accuracy for a fast implementation that's correct for the overwhelming majority of ordinary writing.

Paragraph counting splits on blank lines — one or more newlines with only whitespace between them, matched with /\n\s*\n+/ — which matches how paragraphs are conventionally separated in plain text and markdown. Reading time then falls out of the word count directly: word count divided by 200 words per minute, rounded up to the nearest whole minute, with a floor of 1 minute so a short snippet never reports “0 min.” For more on where that 200 wpm baseline comes from, see our reading time and readability guide.

How keyword density is calculated

The keyword density table works in a few clear steps. First, the input text is lowercased and every run of letters, digits, or apostrophes is extracted with /[a-z0-9']+/g — this strips out punctuation and whitespace as delimiters while keeping contractions like “it's” intact as single tokens. Next, single-character tokens are dropped, and every remaining word is checked against a built-in stopword list of roughly 150 common English function words — “the,” “and,” “of,” “is,” and so on — so the density table surfaces meaningful, topic-carrying words instead of being dominated by grammatical glue words that appear in every English sentence regardless of subject.

From there it's a straightforward frequency count: each word's percentage is its count divided by the total number of non-stopword tokens, multiplied by 100, and rounded to one decimal place. Results are sorted by count descending, with ties broken alphabetically, and the top ten are displayed. This is exactly the kind of on-page keyword density check SEO writers use to spot unintentional overuse of a term — and because it runs entirely client-side, you can paste in drafts you'd never want to upload to a third-party SEO tool.

How the case converter splits words

Converting between casing styles requires first breaking the input into individual words, which is trickier than it sounds once the input might already be in camelCase or PascalCase. The tool handles this with a two-step process: first, it inserts a space at every lowercase-to-uppercase transition (so userAccountId becomes user Account Id before further splitting), then it splits on any run of characters that isn't a letter, digit, or apostrophe. That combination correctly recovers word boundaries whether the input is already snake_case, kebab-case, space-separated prose, or camelCase — a single splitting function feeds all nine output styles (UPPERCASE, lowercase, Title Case, Sentence case, camelCase, PascalCase, snake_case, kebab-case, and aLtErNaTiNg CaSe). For where each of those styles is actually used, see our text case styles explainer.

The diff checker's LCS algorithm

The diff checker is the most algorithmically interesting tool on this page, and it runs entirely without any external diff library. It compares two texts line by line using the classic longest common subsequence (LCS) approach: both inputs are split into arrays of lines, and a dynamic-programming table is built where each cell dp[i][j] holds the length of the longest sequence of lines common to both texts starting from line i in the original and line j in the changed version. The table is filled from the bottom-right corner backward — if the lines at positions i and j match, the cell inherits dp[i+1][j+1] + 1; if they don't, it takes whichever neighboring cell (right or down) represents the longer common subsequence.

Once the table is built, a second pass walks forward through it to reconstruct the diff: matching lines are marked unchanged and both pointers advance together; where lines differ, the algorithm follows whichever direction the table says holds the longer remaining common subsequence, marking a line removed (from the original) or added (from the changed version). This produces a minimal-edit diff — the smallest set of added/removed lines that explains the difference, which is what makes a diff readable instead of noisy.

This method has a known, deliberate trade-off: it's a line-based diff, not a word- or character-based one, and its time and memory cost scale with the product of the two texts' line counts (O(n×m)). For textarea-sized input — a paragraph to a few thousand lines — that's fast and unnoticeable, but it would slow down badly on a full novel-length manuscript or a multi-megabyte log file, a reasonable trade-off for a tool aimed at comparing drafts, code snippets, and config files rather than enormous documents.

Why everything runs client-side

Every function described above runs entirely in JavaScript inside your browser tab. Nothing you type into any of the four tools is ever sent to a server or stored anywhere outside your own machine — there's no backend at all, just static files. That's a deliberate choice: it means you can paste sensitive drafts, unpublished manuscripts, or proprietary code into the diff checker or word counter without a privacy trade-off, and the tools work identically offline once the page has loaded.

Curious how the underlying numbers apply to your own writing? Head back to the tools and try them on a real draft, or read our companion guides on word count standards and reading time and readability.

Keep reading