Tabs vs. Spaces: The War Is Over

Tabs vs. Spaces: The War Is Over
The great indentation war is over and it seems like we have a clear winner.
Every now and then, while exploring a new programming language, I inevitably stumble upon a heated debate, often buried deep in a GitHub issue thread, where contributors are passionately arguing over whether the language’s formatter should default to tabs or spaces. Over the past few months, as I’ve been immersing myself in Zig, I encountered one such discussion.
It got me thinking: After decades of writing code, how is it that we still haven’t reached a consensus on the tabs vs. spaces debate? Sure, personal preferences will always vary, but shouldn’t we, at this point, be able to look at the broader data and settle the matter by majority rule?
So, I went looking for answers.
The state of indentation
To explore this question, I examined the default indentation conventions of the most popular programming languages and markup formats, along with a few niche ones. The list is based on official language style guides where available, or well-established third-party guides where not. The result is a relatively comprehensive snapshot of current best practices:
Language | Default indentation | References |
---|---|---|
Ada | Spaces (3) | 1 |
Ansible (follows YAML) | Spaces (2) | 1 |
Apex | Spaces (4) | 1 |
Assembly (x86, ARM) | Tabs (8) | 1 2 |
Befunge | Spatial | 1 |
Brainfuck | None | 1 |
C / C++ | Tabs or Spaces (2, 4, 8) | 1 2 |
C# | Spaces (4) | 1 |
Clojure | Spaces (2) | 1 |
COBOL | Spaces (4) | 1 |
Cow | None | 1 |
Crystal | Spaces (2) | 1 |
CSS | Spaces (2) | 1 |
Dart | Spaces (2) | 1 2 |
Delphi | Spaces (2) | 1 |
Elixir | Spaces (2) | 1 |
Erlang | Spaces (4) | 1 |
F# | Spaces (4) | 1 |
Fortran | Spaces (2 or 4) | 1 |
Gherkin (Cucumber) | Spaces (2) | 1 |
Go | Tabs (4) | 1 |
Groovy | Spaces (4) | 1 |
Hack | Spaces (2) | 1 |
Hare | Tabs (8) | 1 |
Haskell | Spaces (2 or 4) | 1 |
HTML | Spaces (2) | 1 |
INTERCAL | None | 1 |
Java | Spaces (2 or 4) | 1 2 |
JavaScript | Spaces (2) | 1 |
JSFuck | None | 1 |
JSON | Spaces (2) | 1 |
Julia | Spaces (4) | 1 |
Kotlin | Spaces (4) | 1 |
Less | Spaces (2) | 1 |
Lisp (Common Lisp) | Spaces (2) | 1 |
LOLCODE | Tabs | 1 |
Lua | Spaces (2) | 1 |
Makefile | Tabs (8) | 1 |
Malbolge | None | 1 |
Markdown | Spaces (2 or 4) | 1 |
MATLAB | Spaces (3 or 4) | 1 |
Nim | Spaces (2) | 1 |
Objective-C | Spaces (2) | 1 2 |
OCaml | Spaces (2) | 1 |
Odin | Tabs (4) | 1 |
Perl | Spaces (4) | 1 |
PHP | Spaces (4) | 1 |
Piet | None | 1 |
Prolog | Spaces (2 or 4) | 1 |
Python | Spaces (4) | 1 |
R | Spaces (2 or 4) | 1 |
ReScript | Spaces (2) | 1 |
Ruby | Spaces (2) | 1 |
Rust | Spaces (4) | 1 |
Scala | Spaces (2 or 4) | 1 |
Scheme | Spaces (2) | 1 |
SCSS/Sass | Spaces (2) | 1 |
Shakespeare | Spaces | 1 |
Shell (Bash) | Spaces (4) | 1 |
Solidity | Spaces (4) | 1 |
SQL | Spaces (2 or 4) | 1 |
Swift | Spaces (2 or 4) | 1 2 |
Terraform | Spaces (2) | 1 |
TOML | Spaces (2) | 1 |
TypeScript | Spaces (4) | 1 |
VB.NET | Spaces (4) | 1 |
Verilog | Spaces (4) | 1 |
VHDL | Spaces (2 or 4) | 1 |
Whitespace | Spaces | 1 |
XML | Spaces (2) | 1 |
YAML | Spaces (2) | 1 |
Zig | Spaces (4) | 1 2 |
Roughly 90% of mainstream programming languages and markup formats adopt spaces as the preferred method of indentation. The use of tabs, by contrast, is relatively uncommon and typically reserved for a few notable exceptions. Languages such as Go, Odin, Hare, and Assembly explicitly recommend or rely on tabs, while C and C++ often leave indentation style to the discretion of individual projects or organizations, resulting in a mix of conventions.
Go, in fact, stands out as a rare example where the language’s core developers chose to enforce the use of tabs through tooling, rather than relying on a mere style guide. This decision effectively eliminates the possibility of using spaces for indentation altogether, for better or for worse.
Majority rule
However, the prevailing preference for spaces reflects a broader trend in standardization, much like the global shift toward the metric system or the dominance of right-hand traffic, regardless of any perceived advantages offered by the alternatives. And while there are specific domains, such as aviation or seafaring, where systems like the imperial unit still prevail over the metric, the world at large has gradually converged on a common standard. In much the same way, the majority of developers and style guides have come to favor spaces over tabs, suggesting that, for most practical purposes, the debate has largely been settled.
And so, it seems that, regardless of all the pros and cons, the Tabs vs. Spaces war is over, and that spaces have emerged victorious. But as with any cultural choice in technology, the question lingers:
Is it truly over? ;-)
Enjoyed this? Please consider supporting my work.
What's Your Reaction?






