Count Occurrences runs in your browser as a direct API alternative for literal text matching, so the entire search happens locally without uploading source text, registering for a key, or staying inside a rate limit. You paste up to 1,000,000 characters of text, enter the literal string to find, and choose case-sensitive or case-insensitive matching along with an explicit overlap or non-overlap mode. The tool then reports the full total and shows the first 100 zero-based starting positions. Every comparison uses literal characters rather than regular expressions, so punctuation such as periods, brackets, and asterisks never needs escaping, and an invalid pattern can never break the search. The search string can contain spaces, tabs, line breaks, emoji, or ordinary Unicode text up to 1,000 characters, which makes this a practical replacement for a small REST counter endpoint whenever you need to know how many times a token, ID, separator, log marker, or exact phrase appears in a document. There is no upload step, no JSON envelope, and no server to monitor — open the page, paste, count, and close the tab.

count occurrences api alternative
Count Occurrences API Alternative: Run It Locally

Why People Search for an API Alternative for Counting Occurrences

Most counter APIs were built to increment a single integer at a key — useful for page views, button clicks, and other numerical tallies — but they are a poor fit when you need to count how many times a literal substring appears inside a body of text. The shape of the request is wrong: you are not asking "add one to bucket X", you are asking "how many times does this exact string appear in this exact document". Once a counter endpoint shuts down, every project that depends on it stops working too. A locally running tool removes that single point of failure because there is nothing to go down.

Hosted endpoints also come with recurring friction: signing up for an account, generating a key, watching rate limits, paying for higher tiers, and accepting that every request leaves your machine. For a one-off counting task, that overhead is rarely worth it. The browser already has the matching primitive built in, and a thin tool page can wrap it in a few lines of ordinary runtime code.

Privacy is the third reason. Source documents can include log lines, internal IDs, customer names, or other content you do not want to send to a third-party server. A local tool keeps the bytes inside the tab, which matters whenever the text you are measuring is itself the reason you need a count in the first place. None of that requires giving up the convenience of a real, structured answer.

How the Local Approach Replaces an Endpoint

Count Occurrences performs every comparison inside the current tab using JavaScript string methods that already ship with every modern browser. The matching loop calls String.prototype.indexOf repeatedly from the current offset, either advancing by one code unit in overlap mode or by the full length of the search string in non-overlap mode. Case folding uses String.prototype.toLocaleLowerCase with the English locale, so A and a are treated as the same letter only when you ask for case-insensitive matching. Neither input is sent to Lizely, and there is no compiled regular expression, so an invalid pattern can never break the search.

The input contract is conservative on purpose. Source text is bounded to 1,000,000 characters and the literal search string to 1,000 characters. These limits protect browser responsiveness and prevent an accidental huge result from freezing the tab. An empty search string is rejected outright, because it would match at every boundary and produce an ambiguous result. A search string longer than the remaining source naturally returns zero. Editing any input or option clears the previous output, so stale counts cannot be mistaken for current settings. The tool does not trim source text, change line endings, collapse whitespace, remove duplicates, or rewrite the input; counts and offsets are reported against the exact bytes you paste.

Counting Literal Matches Step by Step

  1. Paste or type the source text you want to search. The field accepts up to 1,000,000 characters, including spaces, tabs, line breaks, emoji, and ordinary Unicode text.
  2. Enter the literal text to find in the search field. The search string can also contain spaces, tabs, line breaks, and emoji, up to 1,000 characters. No escaping is needed for periods, brackets, asterisks, or any other punctuation.
  3. Choose case-sensitive or case-insensitive matching. Pick overlap mode if you want every match including those that share characters with the previous match, or non-overlap mode to count how many separate replacements a simple literal replace would make.
  4. Read the total match count and the first 100 zero-based starting positions. Editing any field clears the previous numbers, so the display always reflects the current inputs and options.

Overlap vs Non-Overlap Mode

The two modes answer different questions, and the right one depends on what "a match" means in your context. The tool exposes both explicitly so you do not have to guess at the engine's default behavior.

ModeAdvance rule after each matchQuestion it answersExample: searching "aa" in "aaaa"
Non-overlapJump past the full search string lengthHow many separate replacements would a simple literal replace make?Positions 0 and 2, total 2
OverlapJump one JavaScript code unitHow many starting positions satisfy the literal pattern?Positions 0, 1, and 2, total 3

For ordinary text-cleaning tasks where you intend to replace every match, non-overlap mode mirrors what Find and Replace Text would actually do. For sequence analysis — counting runs, repeated characters, repeated tokens inside a code fragment, or log markers that can legitimately share boundaries — overlap mode is the more honest answer. Pick the mode that matches your question, not the one that returns the larger number by default.

How Position Numbers Are Reported

The starting positions shown next to the total are zero-based JavaScript string offsets. The first character of the source text sits at position 0, the next at position 1, and so on. For most ordinary English text each visible character consumes one offset, which makes positions easy to map onto character indexes in other tools and editors.

Two caveats apply to non-ASCII content. Characters represented by JavaScript surrogate pairs — which includes most emoji and some CJK code points — consume two UTF-16 code units rather than one perceived character, so the reported offset counts units, not user-perceived graphemes. Locale-specific equivalence, normalization between composed and decomposed Unicode forms, accent folding, and script-specific case rules are not inferred; case-insensitive matching uses English-locale lowercase behavior only. If your search needs grapheme or collation awareness, treat the offsets as a reproducible JavaScript reference rather than a linguistic index.

The position preview is capped at 100 entries so a result with hundreds of thousands of matches still renders quickly and stays readable, but the total at the top is not truncated. A zero result is a valid answer and simply displays no positions. Singular and plural labels follow the actual count, so "1 match" and "0 matches" both render correctly. The operation is deterministic for the same inputs and options: there is no network call, no randomness, no external table, and no server state involved.

Count Occurrences is a literal counter, not a fuzzy matcher, regex engine, or replacement editor. For counts by word rather than by a specific string, Word Counter gives you per-word totals and a reading-time estimate without uploading the text. For changing matches instead of only counting them, Find and Replace Text applies the same literal matching rules and can rewrite every match in one pass. For comparing two bodies of text line by line, the Text Diff Checker shows additions, deletions, and unchanged lines. To put a position number in front of each line of pasted text, the Add Line Numbers to Text tool produces a numbered copy you can paste anywhere. Each tool in this family uses the same local-only contract: no upload, no key, no rate limit, no signup, no server-side state to worry about.

When a Local Browser Tool Is the Better Choice

Choose a local browser tool like Count Occurrences when the answer you need is purely numeric, the input is text you already have on hand, and you do not need the count to be persisted across sessions or shared between users. Choose a hosted counter API only when you need a single tally that survives page reloads, is visible to other clients, or drives a public display. Those are different jobs: one is a measurement, the other is a stateful counter, and conflating them leads to brittle pipelines. For measurement, the browser is the better environment. For stateful counters, a hosted endpoint is still the right tool, and Count Occurrences is intentionally not trying to be one.

Related reading: Extract Emails From Outlook Text in Your Browser Locally.

Related reading: Bulk Text Replace: Replace Every Literal Match Locally.