Prettier 05 ๐จ Core Options โ printWidth, tabWidth, semi, and singleQuote
Prettier has a small set of options that adjust its output. Four of them appear in almost every configuration file and account for most of the formatting differences between projects: printWidth, tabWidth, semi, and singleQuote. None of them changes what Prettier can format or how it parses code. They change the shape of the printed resultโwhere lines break, how deep indentation goes, whether statements end with semicolons, and which quote character wraps strings.
This chapter covers these four options in depth: their defaults, their valid values, how they interact with Prettier’s printing algorithm, and why changing one often produces unexpected changes elsewhere. It also covers the overrides mechanism that lets a single configuration apply different values of these options to different file types, and the limits of what these options can control. By the end, you will understand why printWidth is a guideline rather than a rule, why tabWidth is not the same as “use tabs,” and why semi and singleQuote are the two options teams most often argue about and least often need to.
Key point: These four options control presentation, not behavior. printWidth is a target the printer tries to respect but can exceed when a line cannot be broken. tabWidth sets indentation width, not whether tabs are used. semi and singleQuote toggle two binary choices that Prettier otherwise decides on its own.
Why these four options dominate configuration
The lines-are-long problem. Code lines grow. Function signatures accumulate parameters, object literals accumulate properties, and chained method calls accumulate steps. Without a line-length target, Prettier would print everything on one line or break at arbitrary points. printWidth gives the printer a goal: keep lines under this many characters when possible. The “when possible” qualifier is what makes this option misunderstood. Prettier does not truncate or wrap strings, variable names, or URLs to meet the target. It breaks at syntactic boundaries that exist in the AST, and if no such boundary exists before the target is exceeded, the line exceeds the target .
The indentation-width problem. Different projects use different indentation widths. Two spaces is common in JavaScript and TypeScript; four spaces is common in Python-influenced codebases and some C-family styles. tabWidth tells Prettier how many spaces to use per indentation level when it prints the output. It does not control whether the output uses tabs or spaces. Prettier prints spaces by default. If a project wants tabs, that is a separate decision that Prettier’s printer handles based on the input and the useTabs option, which is outside the scope of these four core options.
The semicolon and quote debate. semi and singleQuote are binary toggles that produce visible, immediate differences in every file. They are also the two options most likely to appear in a team’s style guide and most likely to be debated during onboarding. The Prettier philosophy is that once the team picks a value, the debate ends, because the formatter enforces it without exception. The defaults are semi: true and singleQuote: false, which means Prettier prints semicolons and double quotes unless told otherwise .
a. printWidth: the line-length target
printWidth specifies the line length the printer will try not to exceed. The default is 80 characters. The documentation for Prettier’s options describes it as a “line length that the printer will wrap on” but notes that it is not a hard maximum.
{
"printWidth": 100
}
The printer measures the intermediate representation of each node and decides whether to break it across lines. For a function call with arguments, it checks whether the entire call fits within printWidth. If it does, the call stays on one line. If it does not, the printer breaks the arguments onto separate lines. For an object literal, the same logic applies: if all properties fit, the object stays compact; if not, each property gets its own line.
The option cannot break constructs that have no break points. A long string literal is printed as-is. A long identifier is printed as-is. A long comment may be reformatted if the parser supports comment wrapping for that language, but the printWidth value alone does not force a break inside a string or a name. This is why the documentation warns that printWidth is a guideline, not a strict limit .
// printWidth: 80
// This line exceeds 80 characters because the string cannot be broken
const message = "This is a very long string literal that will not be wrapped by Prettier";
// This line can be broken at the object boundaries, so it will be
const config = { semi: false, singleQuote: true, printWidth: 100, tabWidth: 2 };
// After Prettier with printWidth 80, the object is broken:
const config = {
semi: false,
singleQuote: true,
printWidth: 100,
tabWidth: 2,
};
b. tabWidth: indentation width
tabWidth specifies the number of spaces per indentation level. The default is 2. The option is commonly confused with “use tabs,” which is controlled by a different option (useTabs) that defaults to false. When useTabs is false and tabWidth is 4, Prettier prints four spaces per indentation level. When useTabs is true and tabWidth is 4, Prettier prints one tab per indentation level, and the tab is expected to render as four columns wide in the editor.
{
"tabWidth": 4
}
Changing tabWidth affects every nested construct: function bodies, object literals, arrays, control flow blocks, and JSX children. It does not affect the line-length target. A line that fit within printWidth at tabWidth: 2 may exceed it at tabWidth: 4 because the indentation consumed more characters. The printer accounts for this when deciding where to break, so increasing tabWidth can cause more lines to break.
c. semi: trailing semicolons
semi controls whether Prettier prints semicolons at the end of statements. The default is true. Setting it to false omits semicolons wherever they are optional, which in JavaScript means almost everywhere except in specific constructs like for loop headers and before lines that begin with (, [, or `, where a leading semicolon is required to avoid parsing ambiguity.
{
"semi": false
}
Prettier is careful about the cases where omitting a semicolon changes the parse. When semi is false, it will still print a semicolon at the start of a line that would otherwise be interpreted as a continuation of the previous expression. This is why the output is safe to run even with semicolons disabled. The option is not “remove all semicolons”; it is “omit optional semicolons and preserve required ones.”
d. singleQuote: quote style
singleQuote controls whether Prettier uses single quotes or double quotes for string literals. The default is false, which means double quotes. Setting it to true uses single quotes.
{
"singleQuote": true
}
Prettier does not blindly convert every quote. It counts the quote characters inside the string and chooses the quote style that requires fewer escapes, unless the configuration explicitly overrides that behavior. A string containing an apostrophe will use double quotes even when singleQuote is true, because that avoids escaping the apostrophe. A string containing double quotes will use single quotes even when singleQuote is false. The option sets the preferred style, not an absolute rule that ignores content.
Complete Example Session
// ============================================
// PART 1: DEFAULT CONFIGURATION
// ============================================
// Prettier's defaults for these four options:
{
"printWidth": 80,
"tabWidth": 2,
"semi": true,
"singleQuote": false
}
// The defaults are conservative and widely compatible.
// ============================================
// PART 2: CHANGING printWidth
// ============================================
{
"printWidth": 100
}
// Longer lines are tolerated before the printer breaks.
// Fewer object literals and calls will be split across lines.
// ============================================
// PART 3: CHANGING tabWidth
// ============================================
{
"tabWidth": 4
}
// Four spaces per indentation level instead of two.
// May cause more line breaks because indentation consumes
// more of the printWidth budget.
// ============================================
// PART 4: DISABLING SEMICOLONS
// ============================================
{
"semi": false
}
// Optional semicolons are omitted.
// Required semicolons (for loop headers, leading semicolons
// before lines starting with ( [ `) are still printed.
// ============================================
// PART 5: USING SINGLE QUOTES
// ============================================
{
"singleQuote": true
}
// Single quotes are preferred, but strings containing
// apostrophes may still use double quotes to avoid escapes.
// ============================================
// PART 6: COMBINING ALL FOUR
// ============================================
{
"printWidth": 100,
"tabWidth": 4,
"semi": false,
"singleQuote": true
}
// This is a common team configuration.
// Each option affects a different aspect of the output.
// ============================================
// PART 7: OVERRIDES FOR JSON FILES
// ============================================
{
"semi": true,
"singleQuote": true,
"overrides": [
{
"files": "*.json",
"options": {
"singleQuote": false
}
}
]
}
// JSON does not support single-quoted strings.
// The override ensures JSON files use double quotes
// even when JavaScript files use single quotes.
// ============================================
// PART 8: INPUT AND OUTPUT WITH semi: false
// ============================================
// Input (with semicolons):
const x = 1;
const y = 2;
// Output with semi: false:
const x = 1
const y = 2
// But a leading semicolon is preserved when needed:
const a = 1
;[1, 2, 3].forEach(fn)
// The semicolon before the array literal prevents
// it from being parsed as indexing into `1`.
// ============================================
// PART 9: QUOTE SELECTION WITH singleQuote: true
// ============================================
// Input:
const greeting = "Hello";
const apostrophe = "It's fine";
const quotes = 'She said "hello"';
// Output with singleQuote: true:
const greeting = 'Hello'
const apostrophe = "It's fine" // double quotes kept to avoid escape
const quotes = 'She said "hello"' // single quotes kept
// ============================================
// PART 10: VERIFYING WHICH OPTIONS APPLY
// ============================================
// Run Prettier with --find-config-path to see the config
// Run Prettier with --check to see if files match the config
//
// To inspect the effective options for a file:
// npx prettier --find-config-path src/app.js
// Then read the file it returns.
The ten parts covered the defaults, each option individually, their combination, overrides for file types, the semicolon-omission behavior, quote selection logic, and verification.
Quick Reference
The four core options
| Option | Default | Type | Effect |
|---|---|---|---|
printWidth | 80 | number | Line length target (guideline) |
tabWidth | 2 | number | Spaces per indentation level |
semi | true | boolean | Print trailing semicolons |
singleQuote | false | boolean | Prefer single quotes |
Interaction effects
| Change | Consequence |
|---|---|
Increase printWidth | Fewer line breaks |
Decrease printWidth | More line breaks |
Increase tabWidth | More line breaks (indentation consumes budget) |
Set semi: false | Optional semicolons omitted; required ones kept |
Set singleQuote: true | Single quotes preferred; escapes avoided |
Overrides usage
| Key | Purpose |
|---|---|
files | Glob(s) matching files for this override |
options | The four options (and others) to apply |
excludeFiles | Glob(s) excluding files from this override |
Best Practices
โ Do This:
// Set printWidth to a value the team agrees on
{ "printWidth": 100 } // โ
// Use overrides for file types that need different quote rules
{ "overrides": [{ "files": "*.json", "options": { "singleQuote": false } }] } // โ
// Pick semi and singleQuote once and enforce them
{ "semi": false, "singleQuote": true } // โ
# Verify which config applies before formatting
npx prettier --find-config-path src/app.js # โ
โ Don’t Do This:
// Treat printWidth as a hard maximum
{ "printWidth": 40 } // โ (excessive breaking)
// Assume tabWidth controls tabs vs spaces
{ "tabWidth": 4 } // โ (does not use tabs)
// Set singleQuote: true and expect every string to use single quotes
{ "singleQuote": true } // โ (escapes may override)
// Use different semi values across packages in one repo
// without overrides // โ (inconsistent output)
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
Lines still exceed printWidth | The line has no breakable point | Accept it; printWidth is a guideline |
| Indentation looks wrong | tabWidth is not the same as useTabs | Set useTabs separately if tabs are desired |
Semicolons still appear with semi: false | Leading semicolons are required for parse safety | Expected behavior; do not remove |
Strings use double quotes despite singleQuote: true | The string contains an apostrophe | Expected; Prettier avoids escapes |
| Different files format differently | A nearer config or override applies | Check --find-config-path for each file |
Real-World Examples
1. Default configuration
{ "printWidth": 80, "tabWidth": 2, "semi": true, "singleQuote": false }
2. Common team configuration
{ "printWidth": 100, "tabWidth": 2, "semi": false, "singleQuote": true }
3. Four-space indentation
{ "tabWidth": 4 }
4. No semicolons
{ "semi": false }
5. Single quotes
{ "singleQuote": true }
6. JSON override for double quotes
{ "singleQuote": true, "overrides": [{ "files": "*.json", "options": { "singleQuote": false } }] }
7. Wider lines for TypeScript
{ "printWidth": 120 }
8. Narrow lines for Markdown
{ "overrides": [{ "files": "*.md", "options": { "printWidth": 80 } }] }
9. Verify config path
npx prettier --find-config-path src/index.ts
10. Check formatting against config
npx prettier src/ --check
Visual
printWidth as a guideline
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ printWidth: 80 โ
โ โ
โ Line: const x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }; โ
โ Length: 52 characters โโโบ fits, stays on one line โ
โ โ
โ Line: const x = { alpha: 1, beta: 2, gamma: 3, delta: 4 }; โ
โ Length: 61 characters โโโบ fits, stays on one line โ
โ โ
โ Line: const veryLongIdentifierName = "a string that cannot"โ
โ Length: 90 characters โโโบ exceeds, but string cannot break โ
โ Result: printed as-is โ
โ โ
โ Line: const x = { aVeryLongPropertyName: 1, another: 2 }; โ
โ Length: 78 characters โโโบ fits (barely) โ
โ โ
โ Line: const x = { aVeryLongPropertyName: 1, anotherLong: 2 };โ
โ Length: 82 characters โโโบ exceeds, object CAN break โ
โ Result: broken across lines โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
tabWidth vs useTabs
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ INDENTATION OPTIONS โ
โ โ
โ tabWidth: 2, useTabs: false โ
โ function foo() { โ
โ return 1; โ
โ } โ
โ (two spaces per level) โ
โ โ
โ tabWidth: 4, useTabs: false โ
โ function foo() { โ
โ return 1; โ
โ } โ
โ (four spaces per level) โ
โ โ
โ tabWidth: 4, useTabs: true โ
โ function foo() { โ
โ โ return 1; โ
โ } โ
โ (one tab per level, rendered as 4 columns) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
semi: false and leading semicolons
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ semi: false โ
โ โ
โ Input: โ
โ const x = 1; โ
โ const y = 2; โ
โ โ
โ Output: โ
โ const x = 1 โ
โ const y = 2 โ
โ โ
โ But: โ
โ const a = 1; โ
โ [1, 2, 3].forEach(fn); โ
โ โ
โ Output: โ
โ const a = 1 โ
โ ;[1, 2, 3].forEach(fn) โ
โ โ โ
โ Leading semicolon preserved to prevent โ
โ the array from being parsed as a[1] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
singleQuote and escape avoidance
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ singleQuote: true โ
โ โ
โ Input: โ
โ const a = "Hello"; โ
โ const b = "It's fine"; โ
โ const c = 'She said "hello"'; โ
โ โ
โ Output: โ
โ const a = 'Hello' (single, no escape) โ
โ const b = "It's fine" (double, avoids escape) โ
โ const c = 'She said "hello"' (single, no escape) โ
โ โ
โ Prettier chooses the quote style that requires โ
โ fewer escapes, even when singleQuote is true. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
printWidth default | 80 |
printWidth behavior | Guideline, not hard maximum |
tabWidth default | 2 |
tabWidth behavior | Spaces per indentation level (not tabs) |
semi default | true |
semi: false behavior | Omit optional semicolons; keep required ones |
singleQuote default | false |
singleQuote: true behavior | Prefer single quotes; escapes may override |
| Override mechanism | overrides with files and options |
Key takeaways:
printWidthis a target, not a limit. Prettier breaks lines at syntactic boundaries and cannot break strings, identifiers, or URLs. Lines will exceed the target when no break point exists.tabWidthcontrols indentation width, not tab usage. Prettier prints spaces by default. Tab characters require a separate option (useTabs).semi: falsedoes not remove all semicolons. It removes optional ones and preserves the leading semicolons required to prevent parsing ambiguity.singleQuote: truedoes not force every string to use single quotes. Prettier selects the quote style that avoids escapes, so strings containing apostrophes may still use double quotes.- Overrides let one configuration handle multiple file types. A project can use single quotes for JavaScript and double quotes for JSON without separate configuration files.
- Changing
tabWidthcan change line breaks. Indentation consumes part of theprintWidthbudget, so wider indentation can cause more lines to exceed the target and break.
Remember: These four options are presentation decisions, not behavioral ones. They do not change what code does, only how it looks. printWidth and tabWidth shape the geometry of the output; semi and singleQuote toggle two binary choices that Prettier otherwise decides based on context. Set them once, document them in .prettierrc, and stop thinking about them. The purpose of configuration is not to perfect every line; it is to remove the need to discuss formatting at all.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!