A line is whatever sits between two newline boundaries, and the most reliable way to count lines in file content is to paste the text into a browser tool that reports total, non-blank, blank, and longest-line numbers against explicit boundary rules. The reason one file can produce two different line totals in two different programs almost always comes down to which characters count as separators and whether a trailing empty segment is included. LF (line feed), CRLF (carriage return plus line feed), and a lone CR each create one boundary, and CRLF is treated as a single boundary rather than two. Once any character exists, the text contains at least one line, and a newline at the very end always adds a final empty line on top of whatever came before. The result you get from the Line Counter is anchored to those rules and to Unicode code points rather than to UTF-16 code units, grapheme clusters, or display columns, so the same pasted text always produces the same number.

Why "count lines in file" rarely means the same thing in two tools
Most line-counting discrepancies come from three places: the choice of separator, the treatment of the final segment, and the way the longest line is measured. A Linux command may count newline characters, a Windows tool may treat a file as a stream of records, a text editor may suppress a final empty line, and a poetry formatter may treat stanza breaks as something other than a paragraph. The Line Counter takes one position on each of these questions and states it, so you can match its numbers against the rule rather than against a specific program. If you have ever pasted a file into two different counters and gotten two answers, the boundary rule is almost always the cause.
How to count lines in file content
The fastest path is to drop the text into the editor and read the four numbers that update as you type or paste.
- Open the Line Counter in your browser.
- Paste the file content into the editor, or type directly. No upload or submit button is required.
- Read the four statistics: total lines, non-blank lines, blank or whitespace-only lines, and longest line in code points.
- Verify the cross-check: non-blank plus blank should equal total for every result.
- Glance at the newline and Unicode rules printed under the results before comparing the number to another tool.
The same input pasted twice produces the same numbers in any supported browser, because the analysis is a deterministic local function.
What the boundary rules actually look like
A line boundary is one of three things: an LF (0x0A), a CRLF pair (0x0D 0x0A), or a lone CR (0x0D). CRLF is treated as a single boundary, not two, so a file written on Windows and a file written on Unix that contain identical visible lines will still produce the same total once the endings are normalized. Mixed endings are accepted in the same input, which is useful when text has been moved between a Unix shell, a Windows clipboard, and a classic Mac archive.
Empty input is the only case defined as zero lines. Once the editor contains any character at all, the text contains at least one line. A newline at the very end of the input adds a final empty line on top of whatever came before, and that rule is never silently changed based on whether the last visible line happens to contain text.
The four cases below show how specific inputs resolve under these rules. The longest line is measured in code points, not visual columns or bytes.
| Input | Total | Non-blank | Blank | Longest line (code points) |
|---|---|---|---|---|
| (empty) | 0 | 0 | 0 | 0 |
| alpha | 1 | 1 | 0 | 5 |
| alpha + LF | 2 | 1 | 1 | 5 |
| CRLF alone | 2 | 0 | 2 | 0 |
In every row, non-blank plus blank equals total, which is a quick way to spot a misconfigured tool or a paste that lost characters on the way in. The same logic extends directly: a file ending in two consecutive newlines produces a non-blank content segment plus two trailing blank segments, because each newline boundary creates a new empty side.
Blank versus non-blank lines
A line is blank when the JavaScript trim function on its contents returns an empty string, which means any line made up entirely of spaces, tabs, or other Unicode whitespace is blank. A line containing a letter or digit is non-blank, and a line that mixes a letter with surrounding spaces is also non-blank, because the trim leaves at least one visible character behind. The original whitespace is not removed from the input, and it still counts toward the longest line in code points, so a thirty-space indent on an otherwise empty line is classified as blank, even though its 30 code points still count toward the longest-line length. The classification is purely about whether something non-whitespace survives the trim.
The total count is always the sum of non-blank and blank lines, which gives you a built-in cross-check for every result the editor reports. If your arithmetic does not line up, the paste is the first place to look, because a smart-quote conversion or a clipboard autoindent can quietly add or remove a separator on the way in.
Longest line in code points, not in characters
The "longest line" metric is measured in Unicode code points, which is a deliberate choice rather than a default. JavaScript stores strings as UTF-16 code units, and the two are not the same when the text contains supplementary characters. A 😀 emoji, for example, occupies two UTF-16 code units but counts as one code point under the Line Counter's longest-line metric. A family emoji joined with zero-width joiners, or an accented letter written as a base character followed by a combining acute accent, contains several code points even though it may render as one visible symbol or one cell. Tabs count as one code point even though many editors display them as several columns.
This means the metric is not the visual width of the line in your editor, not the byte length, and not the number of user-perceived grapheme clusters. The label "Longest line (code points)" and the supporting note under the results are written specifically to prevent you from reading it as a column count. The number will agree across browsers and across sessions because the analysis is a pure local function of the exact UTF-16 code units in the input.
What happens at the input limit
The editor accepts up to 1,000,000 JavaScript UTF-16 code units, measured the same way as the character counter shown under the editor. Text exactly at the limit is processed normally. If the input exceeds the limit by even one code unit, the entire analysis returns an error, every previous statistic is cleared, and the tool never returns a partial count or a silently truncated prefix. The guard is separate from the longest-line code-point metric, so a single supplementary emoji will consume two of your input code units while contributing only one code point to the longest line.
Because the calculation never calls a remote service and never uploads the pasted text, the same input produces the same statistics in every supported browser, and you can rerun the same paste as many times as you need. The Clear button removes the entire input and returns every statistic to zero without affecting anything else on the page.
Why the result can still disagree with a command-line tool
A Linux wc -l and the Line Counter can return different totals for the same file, and the difference is almost always traceable to one of three things: the boundary definition, the handling of a final newline, and the longest-line metric. The wc -l command counts newline characters, so a file that ends without a trailing newline will be one short under wc -l but will still register as one complete line in the Line Counter. A tool that suppresses the final empty segment after a trailing newline will also report a smaller number. PowerShell on Windows may report yet a third number if it counts records rather than separator characters.
If you are moving between a Windows file and a Unix pipeline, the safest path is to first count with the Line Counter against a known input, then compare both numbers against the documented rules. The browser-based approach has the additional benefit of not depending on which operating system you are sitting at, which is the same reason many writers, log analysts, and code reviewers keep a private local counter handy.
For users who still want a quick shell-based sanity check, the guide on counting lines in a file in Linux without command-line hassle shows the equivalent wc -l and PowerShell calls alongside the boundary rules. The two approaches are designed to agree once the same file is in the same form, but the browser tool exposes the rule so the disagreement is explainable rather than mysterious.
What the tool does not do
The Line Counter is deliberately narrow. It does not count words, sentences, bytes, paragraphs, or characters, and it does not produce a numbered preview, because a million-line numbered preview would either freeze the page or create a hidden cap that looks complete. A long line that visually wraps inside the textarea remains one logical line unless the text actually contains an LF, CRLF, or CR separator. If you need a word or character count alongside the line count, the related dedicated counters accept the same paste. The tool also does not normalize Unicode, expand tabs, strip carriage returns that are not part of a separator, or otherwise rewrite your text before analyzing it.
That narrowness is the reason the boundary rules can be stated in one paragraph and held to in every result: there is no normalization layer between your paste and the number on the screen. The classification routine, the longest-line scan, and the input guard all read the same raw UTF-16 code units, which is what makes the same paste produce the same statistics in any supported browser.
For a deeper look, see Dedupe Text: A Practical Guide to Removing Duplicate Lines.