Convert tabs to spaces
Paste code or text and each tab turns into the same number of spaces, four unless you choose another width from 1 to 16, so indentation looks identical in every editor, browser and diff. Line breaks and existing spaces stay untouched. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- function hi() { return true; }
- Result
- function hi() { return true; }
- Input
- function hi() { return true; }
- Text
- function hi() { return true; }
- Spaces per tab
- 4
Code editors, terminal pastes, and markdown sources often mix invisible tab characters with spaces, so indentation looks fine in one tool and shifts in another. This convert tabs to spaces utility expands every U+0009 tab into a fixed width of ASCII spaces—four by default, or any integer from one to sixteen—while leaving newlines, letters, and existing spaces untouched. Empty or whitespace-only strings fail with invalid input so pipelines never store blank conversions. Use it when standardizing repositories for space-only style guides, preparing snippets for browsers that render tabs inconsistently, or cleaning exports before publish.
What convert tabs to spaces means and when to use it
The tool does not re-indent nested blocks, does not compute greatest-common-divisor indent units, and does not refuse mixed styles—it simply expands tabs wherever they appear, including mid-line tab stops used in older tables or Makefile fragments that only need character-level normalization. Prefer this calculator when the search intent is convert tabs to spaces, replace tabs with spaces, tab to space converter, or expand tabs for consistent display.
Typical sources of tabs include copy from IDEs with tab indent, git diffs from mixed teams, CSV or log columns separated by tabs, and legacy scripts that used hard tabs for alignment. Do not confuse this landing with full indentation-level normalizers that detect ragged nesting and rewrite levels to a base unit; that is a different product for a different problem. Existing space characters stay as spaces; only tab code points grow into the chosen pad.
What you can do with it
Space-only style guide enforcement
Expand hard tabs in code snippets and config samples before commit or publish so repositories that ban tabs stay consistent without re-indenting logical levels.
Stable web and markdown display
Convert tabs to spaces in documentation and blog code blocks so browsers and renderers that treat tab width differently show the same alignment.
FAQ
How do I convert tabs to spaces with this tool?
The response result field is the string with every tab expanded to that many spaces.
Does this re-indent nested code levels?
No. It only replaces tab characters with a fixed space width. For detecting and normalizing indent levels, use a dedicated indentation normalizer capability.
Is the convert tabs to spaces tool free?
The browser tool runs free on your device.
What happens to tabs in the middle of a line?
They are expanded too. Every tab becomes exactly the chosen number of spaces wherever it sits, so a tab between two columns turns into the same run of spaces as one at the start of a line.
How can I check how many tabs were replaced?
The result reports the number of tabs replaced and how much longer the text became. In a short three-line function with one indented line, one tab is replaced and the text grows from 31 to 34 characters.
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/tabs-to-spaces \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"function hi() {\n\treturn true;\n}"}'const res = await fetch("https://api.kit.forhosting.com/str/tabs-to-spaces", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "function hi() {\n\treturn true;\n}"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/tabs-to-spaces",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "function hi() {\n\treturn true;\n}"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/tabs-to-spaces", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"function hi() {\\n\\treturn true;\\n}"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"function hi() {\n\treturn true;\n}"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/tabs-to-spaces", 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": "function hi() {\n\treturn true;\n}"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.tabs_to_spaces",
"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
What convert tabs to spaces means and when to use it
Convert tabs to spaces means a single, predictable rewrite: every tab character in the input is replaced by exactly N plain space characters, where N is spaces_per_tab and defaults to four when you omit the field. Empty strings and strings that are only whitespace after trim raise invalid_input, which protects bulk jobs from writing empty cells when a required field was blank.
Input contract, width parameter, and reading the response
Send a JSON body with the required string field text set to the non-empty content you want expanded. Aliases input, value, string, s, content, and body are accepted when older clients or form generators use those names. Optional spaces_per_tab must be an integer from one through sixteen inclusive; omit it to use four spaces per tab, which matches many style guides and editor defaults for soft tabs. Missing text, a non-string value, an empty string, a whitespace-only string, or a spaces_per_tab outside the allowed range 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 result and text with the expanded string, input echoing the exact original for before-and-after UI, spaces_per_tab as the width applied, tabs_replaced as the count of tab characters expanded, chars_before and chars_after as lengths, chars_added as the net growth, and message as a short human summary. Use result alone when you only need the cleaned string; use tabs_replaced when a pipeline logs how aggressive the expand was; use chars_added when estimating storage growth after policy migration from tabs to spaces. Keep payloads to ordinary source files, snippets, and documents suitable for a Worker isolate rather than multi-megabyte dumps.
API usage, pricing, workflows, and practical limits
Call the free in-browser convert tabs to spaces tool for paste cleanup, classroom demos, code-review prep, and quick checks without installing a desktop utility or writing a one-liner in every language. A typical workflow expands tabs in a snippet before publishing documentation so readers on the web see stable indentation regardless of browser tab width. Another workflow standardizes pull-request samples to a project spaces-only convention before lint, while a third cleans tab-delimited paste that should become space-aligned mono text for display only. Do not expect HTML tag stripping, markdown structure rewriting, or smart tab stops that align to column multiples beyond fixed width expansion—those are separate problems. Use the prepaid KIT API when a CI job, CMS, editor plugin, support desk, or mobile client needs the same transform under balance at $0.002 per successful item; validation failures never consume balance after the engine rejects the request. Pair this endpoint with line trimmers or whitespace removers only when the next step is a different SEO intent; keep convert tabs to spaces as its own landing so the search term is not mixed with collapse-spaces or indent-level tools. Authors shipping SDKs can document text as required, spaces_per_tab as optional, and show a multi-tab success example plus an empty-string error example so integrators see both sides of the contract.
Integration use cases
CI fixtures and pipeline sanitization
Normalize fixture files and user-uploaded text to a known space width so equality checks and golden tests stop failing on invisible tab characters.
Technical questions
What happens if text is empty?
Empty strings and whitespace-only strings fail with invalid_input and are not charged.
What does tabs_replaced mean?
It is the number of U+0009 tab characters that were expanded. chars_added is chars_after minus chars_before and reflects how much the string grew.