Tabs vs spaces
Tabs vs spaces for code indentation: accessibility, diffs, and why the debate mostly outlived its technical stakes.
Last updated
The short answer
Spaces render identically everywhere, which is why most modern style guides and formatters (Prettier, Black, PEP 8) default to them — consistency across editors and diffs matters more than the minor storage or accessibility wins tabs offer. If your language's own tooling mandates tabs (Go's gofmt, Makefiles), match that instead of relitigating the debate.
| Dimension | Tabs | Spaces |
|---|---|---|
| Rendering | Varies by editor's tab-width setting | Consistent — 1 space is always 1 space |
| File size | Smaller (1 byte per indent level) | Larger (N bytes per indent level) |
| Accessibility | Width adjustable per user or editor | Fixed width for everyone |
| Alignment | Breaks across differing tab widths | Reliable in any viewer or diff tool |
| Ecosystem default | Go (gofmt); Makefiles require it | Prettier, Black, most style guides |
Choose Tabs when
- →Your language's own tooling mandates it — Makefiles require literal tabs, and Go's gofmt rewrites everything to tabs regardless of preference.
- →Team members have different visual indent-width preferences and you want each editor to honor its own setting.
- →You care about minimizing file size at scale across a very large codebase — a tiny effect, but a real one.
Choose Spaces when
- →You want code to look identical in every editor, terminal, diff tool and code review UI without configuration.
- →You're using a formatter (Prettier, Black, most JS/Python/Ruby style guides) that defaults to spaces — fighting the default costs more than accepting it.
- →Multi-line alignment, like matching parentheses across lines, needs to survive being viewed at any tab width.
The catch nobody mentions
The debate is mostly settled by tooling now, not preference: once a project adopts an auto-formatter, tabs-vs-spaces stops being a per-commit argument and becomes a one-line config setting nobody touches again. The place it still bites is inconsistency — mixing tabs and spaces in one file, which some languages (Python) treat as a syntax error and others render as an invisible mess.