Count lines
Hello, an empty row, World and a final line break count as 4 lines: 2 with content and 2 blank. Windows, Unix and old Mac line endings are all recognized, and each break is counted once. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- Hello World
- Total
- 4
- Non empty
- 2
- Blank
- 2
- Lines
- 4
Counting lines is a small utility that still needs a clear contract: what counts as a line break, whether a trailing newline creates an extra blank line, and how whitespace-only rows are classified. This line counter accepts non-empty text, splits on carriage return, line feed, or CRLF pairs, then reports total lines, non-empty lines that contain at least one non-whitespace character, and blank lines that are empty or only spaces and tabs after trim.
What line counts mean and how blank versus non-empty is decided
A line count answers three related questions people type into search: how many lines does this text have, how many of those lines actually contain content, and how many are blank. This capability defines a line as a segment between line terminators. Terminators are carriage return, line feed, or the Windows-style carriage-return-plus-line-feed pair treated as a single break so a CRLF file is not double-counted.
After splitting, each segment is classified. A line is non-empty when trim removes all leading and trailing whitespace and something remains—letters, digits, punctuation, or other visible characters. A line is blank when the segment is empty or becomes empty after trim, which covers pure spaces, tabs, and completely empty rows between paragraphs.
Total equals non-empty plus blank by construction, so you can assert that identity in tests. A single-line string without any newline yields total one and non-empty one when it has content. A string that ends with a newline yields a trailing blank segment, which matches how many editors and log tools expose an extra empty row at the end of the file.
Prefer this count-lines calculator when the search intent is count lines in text, count blank lines, or total non-empty lines online. Do not use it when you need word counts, character counts as the primary product promise, or byte lengths of binary files—those are different landings.
What you can do with it
Draft and markdown spacing checks
Writers and editors paste drafts to see total lines versus blank spacer rows before publishing blog posts or README files.
Logs and support paste audits
Support tools count non-empty log lines in customer pastes and report blank-line noise without installing local shell utilities.
FAQ
What happens if text is empty?
A zero-length string is rejected and not charged; whitespace-only text is allowed and counted as blank lines.
Does a trailing newline count as an extra line?
Yes. Text ending with a line break includes a trailing blank segment, so total increases by one and blank increases by one.
Is the line counter free?
The browser tool runs free on your device.
How are CRLF and LF handled?
Carriage return, line feed, and CRLF pairs are all treated as line breaks. CRLF counts as a single break so Windows-style files are not double-counted.
Is a line with only spaces counted as blank?
Yes. A line is blank when it is empty or holds nothing but spaces and tabs; any letter, digit or punctuation mark makes it a content line. Text made only of spaces is accepted and reports every line as blank.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/str/line-count \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello\n\nWorld\n"}'const res = await fetch("https://api.kit.forhosting.com/str/line-count", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Hello\n\nWorld\n"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/line-count",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Hello\n\nWorld\n"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/line-count", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Hello\\n\\nWorld\\n"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Hello\n\nWorld\n"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/line-count", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "Hello\n\nWorld\n"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.line_count",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Empty input fails with invalid input so pipelines never store zero-length payloads by accident.
Input contract, empty rejection, and reading the response fields
Whitespace-only text is allowed: it is not empty input, and it correctly reports all lines as blank. Source text follows the same retention rules as other KIT parse items. Send a JSON body with the required string field text set to the non-empty sample you want measured. Aliases input, value, s, content, and body are accepted when older clients or form generators use those names. Missing text, a non-string value, or a zero-length string all raise invalid_input with a message that names the problem, and those failures are not charged on the prepaid API. On success the response includes total as the number of line segments, non_empty as the count of content lines, blank as the count of empty or whitespace-only lines, and convenience aliases lines equal to total, non_empty_lines equal to non_empty, and empty_lines equal to blank so different SDK field names map without extra glue. character_count is the UTF-16 length of the original string for quick size checks next to line stats. original echoes the exact input so UIs can show before-and-after tables without re-storing the payload. method is always line_count so downstream code can branch without sniffing shapes. Use total alone when a progress bar only needs how many rows exist; use non_empty when billing or grading should ignore blank spacer rows; use blank when a style guide or linter-style check cares about empty lines between blocks. Keep payloads to ordinary message and document sizes suitable for a Worker isolate rather than multi-megabyte dumps; this product is a text utility, not a bulk file warehouse.
API usage, pricing, workflows, and practical limits
Call the free in-browser count lines tool for homework checks, paste-bin audits, log previews, and quick blank-line reviews without installing wc or writing a script in every language. A typical workflow pastes draft markdown, counts blank lines between sections, then tightens spacing before publish. Do not expect word counting, sentence splitting, or language-aware paragraph detection—those are separate problems with separate SEO terms. Authors shipping SDKs can document text as the only required field and show a multi-line success example plus an empty-string error example so integrators see both sides of the contract. Use the prepaid KIT API when a CMS, content pipeline, QA harness, or mobile client needs the same contract under balance at $0.002 per successful item; validation failures never consume balance after the engine rejects the request. Pair this endpoint with diff or format tools when the next step is comparing two versions line by line, but keep count lines as its own landing so the count-lines search intent is not mixed with full-file statistics or PDF page counts.
Integration use cases
CI and content pipeline fixtures
Build scripts pin line-count golden outputs so CRLF mishandling or empty-input regressions fail continuous integration immediately.
Technical questions
How do I count lines in text with this tool?
Send JSON with text set to your non-empty string. The response returns total, non_empty, and blank line counts, plus aliases and character_count.