Prettier is an opinionated code formatter that enforces consistent style across multiple languages including JavaScript, TypeScript, Flow, JSX, JSON, CSS, SCSS, Less, HTML, Vue, Angular, GraphQL, Markdown, and YAML.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Document Builder API provides low-level primitives for creating custom formatters and Prettier plugins. It offers a composable system for building formatted output through document objects that represent formatting decisions.
The Document Builder API uses an intermediate representation called "Doc" objects that describe how code should be formatted. These documents are then printed to strings with line breaking, indentation, and spacing applied.
import { doc } from 'prettier';
// Access builder functions
const { builders, printer, utils } = doc;
// Or import specific builders
import { doc } from 'prettier';
const { group, line, indent, join } = doc.builders;function join(separator: Doc, docs: Doc[]): DocJoin an array of documents with a separator document between each element.
Parameters:
separator (Doc): Document to insert between elementsdocs (Doc[]): Array of documents to joinExample:
const params = ['a', 'b', 'c'];
const joined = doc.builders.join(
[',', doc.builders.line],
params
);
// Result: 'a,\nb,\nc' (when broken) or 'a, b, c' (when flat)const line: DocA line break that becomes a space when the parent group fits on one line.
Example:
const statement = doc.builders.group([
'if (',
'condition',
')',
doc.builders.line,
'doSomething();'
]);
// Result: 'if (condition) doSomething();' or 'if (condition)\ndoSomething();'const softline: DocA line break that becomes nothing (empty string) when the parent group fits on one line.
Example:
const array = doc.builders.group([
'[',
doc.builders.softline,
doc.builders.join([',', doc.builders.line], elements),
doc.builders.softline,
']'
]);
// Result: '[a, b, c]' or '[\n a,\n b,\n c\n]'const hardline: DocAn unconditional line break that always creates a new line.
Example:
const statements = [
'const a = 1;',
'const b = 2;'
];
const program = doc.builders.join(doc.builders.hardline, statements);
// Result: 'const a = 1;\nconst b = 2;'const literalline: DocA line break that preserves literal newlines without triggering parent group breaking.
const hardlineWithoutBreakParent: DocAn unconditional line break that doesn't trigger parent group breaking.
const literallineWithoutBreakParent: DocA literal line break that doesn't trigger parent group breaking.
function group(doc: Doc, options?: { shouldBreak?: boolean, id?: symbol }): DocGroup documents that should be formatted consistently - either all on one line or all broken across multiple lines.
Parameters:
doc (Doc): Document to groupoptions (optional): Grouping options
shouldBreak (boolean): Force group to breakid (symbol): Unique identifier for the groupExample:
const functionCall = doc.builders.group([
'functionName(',
doc.builders.indent([
doc.builders.softline,
doc.builders.join([',', doc.builders.line], args)
]),
doc.builders.softline,
')'
]);
// Result: 'functionName(a, b, c)' or 'functionName(\n a,\n b,\n c\n)'function conditionalGroup(docs: Doc[], options?: { shouldBreak?: boolean }): DocTry multiple document variants in order, using the first one that fits.
Example:
const alternatives = doc.builders.conditionalGroup([
// Try inline first
['(', doc.builders.join(', ', args), ')'],
// Fall back to multi-line
[
'(',
doc.builders.indent([doc.builders.line, doc.builders.join([',', doc.builders.line], args)]),
doc.builders.line,
')'
]
]);function fill(docs: Doc[]): DocFill available line space optimally by trying to fit as many documents as possible on each line.
Example:
const words = ['This', 'is', 'a', 'long', 'sentence', 'that', 'should', 'wrap'];
const paragraph = doc.builders.fill(
doc.builders.join(doc.builders.line, words)
);
// Result: Wraps words to fit available widthfunction indent(doc: Doc): DocIncrease indentation level for the contained document.
Example:
const block = [
'{',
doc.builders.indent([
doc.builders.hardline,
'statement1;',
doc.builders.hardline,
'statement2;'
]),
doc.builders.hardline,
'}'
];
// Result: '{\n statement1;\n statement2;\n}'function indentIfBreak(doc: Doc, options?: { groupId?: symbol }): DocConditionally indent the document only if the parent group breaks.
Parameters:
doc (Doc): Document to conditionally indentoptions (object, optional): Options including group ID for specific targetingExample:
const conditional = doc.builders.group([
'if (',
doc.builders.indentIfBreak([
doc.builders.line,
'longCondition'
]),
doc.builders.line,
')'
]);
// Indents only when the group breaksfunction align(n: number | string, doc: Doc): DocAlign document to a specific column offset.
Parameters:
n (number | string): Spaces to align (number) or alignment stringdoc (Doc): Document to alignExample:
const aligned = doc.builders.align(4, [
'let x = longVariableName +',
doc.builders.line,
'anotherLongVariableName;'
]);
// Result: Aligns continuation line to column 4function addAlignmentToDoc(doc: Doc, size: number, tabWidth: number): DocAdd additional alignment space to an existing document.
Parameters:
doc (Doc): Document to add alignment tosize (number): Number of spaces to add for alignmenttabWidth (number): Tab width for calculating proper alignmentExample:
const withAlignment = doc.builders.addAlignmentToDoc(
existingDoc,
4,
2
);
// Adds 4 spaces of alignment considering tab widthfunction dedent(doc: Doc): DocDecrease indentation level for the contained document.
function dedentToRoot(doc: Doc): DocRemove all indentation, aligning to the root level.
function markAsRoot(doc: Doc): DocMark document as root for indentation calculations.
function ifBreak(breakContents: Doc, flatContents?: Doc, options?: { groupId?: symbol }): DocConditionally include content based on whether the parent group breaks.
Parameters:
breakContents (Doc): Content when parent group breaksflatContents (Doc, optional): Content when parent group is flatoptions (optional): Options including group ID to checkExample:
const arrayElements = doc.builders.group([
'[',
doc.builders.indent([
doc.builders.softline,
doc.builders.join([
',',
doc.builders.ifBreak(doc.builders.hardline, doc.builders.line)
], elements)
]),
doc.builders.softline,
']'
]);function lineSuffix(doc: Doc): DocContent that should appear at the end of the current line.
Example:
const statement = [
'const x = value;',
doc.builders.lineSuffix(' // comment')
];
// Result: 'const x = value; // comment'const lineSuffixBoundary: DocBoundary marker for line suffix content placement.
const cursor: DocPlaceholder for cursor position in editor integrations.
const breakParent: DocForce the parent group to break across multiple lines.
Example:
const forceBreak = doc.builders.group([
'items: [',
doc.builders.indent([
doc.builders.line,
'item1,',
doc.builders.breakParent, // Forces parent group to break
doc.builders.line,
'item2'
]),
doc.builders.line,
']'
]);const trim: DocRemove trailing whitespace from the current line.
function label(label: string, doc: Doc): DocLabel document for debugging and development purposes.
function printDocToString(doc: Doc, options: PrintOptions): PrintResultConvert a document to a formatted string with the specified print options.
Types:
interface PrintOptions {
printWidth?: number; // Maximum line width (default: 80)
tabWidth?: number; // Tab width (default: 2)
useTabs?: boolean; // Use tabs for indentation (default: false)
endOfLine?: 'auto' | 'lf' | 'crlf' | 'cr'; // Line ending style
}
interface PrintResult {
formatted: string; // Formatted output
cursorOffset: number; // Cursor position (if cursor doc was used)
}Example:
const document = doc.builders.group([
'function(',
doc.builders.indent([
doc.builders.softline,
doc.builders.join([',', doc.builders.line], parameters)
]),
doc.builders.softline,
')'
]);
const result = doc.printer.printDocToString(document, {
printWidth: 80,
tabWidth: 2,
useTabs: false
});
console.log(result.formatted);function traverseDoc(
doc: Doc,
onEnter?: (doc: Doc) => void | boolean | Doc,
onExit?: (doc: Doc) => void,
shouldTraverseConditionalGroup?: boolean
): voidTraverse document tree with enter/exit callbacks.
function findInDoc(doc: Doc, fn: (doc: Doc) => boolean, defaultValue?: any): anyFind element in document tree matching predicate function.
function mapDoc(doc: Doc, fn: (doc: Doc) => Doc): DocTransform document tree by applying function to each node.
function willBreak(doc: Doc): booleanCheck if document will cause parent group to break.
function canBreak(doc: Doc): booleanCheck if document can break across lines.
function removeLines(doc: Doc): DocRemove all line breaks from document.
function stripTrailingHardline(doc: Doc): DocRemove trailing hard line breaks from document.
function replaceEndOfLine(doc: Doc, replacement?: Doc): DocReplace end-of-line characters in document.
function formatObjectExpression(properties) {
return doc.builders.group([
'{',
properties.length > 0 ? [
doc.builders.indent([
doc.builders.line,
doc.builders.join([',', doc.builders.line], properties.map(formatProperty))
]),
doc.builders.line
] : '',
'}'
]);
}
function formatProperty(prop) {
return doc.builders.group([
prop.key,
': ',
prop.value
]);
}// Example plugin printer function
function print(path, options, print) {
const node = path.node;
switch (node.type) {
case 'CustomNode':
return doc.builders.group([
'custom(',
doc.builders.indent([
doc.builders.softline,
doc.builders.join([',', doc.builders.line],
node.args.map((_, index) => path.call(print, 'args', index))
)
]),
doc.builders.softline,
')'
]);
default:
return '';
}
}function formatArray(elements, options) {
const shouldBreakElements = elements.length > 3 ||
elements.some(el => willBreak(el));
return doc.builders.group([
'[',
elements.length > 0 ? [
doc.builders.indent([
shouldBreakElements ? doc.builders.hardline : doc.builders.softline,
doc.builders.join([
',',
shouldBreakElements ? doc.builders.hardline : doc.builders.line
], elements)
]),
shouldBreakElements ? doc.builders.hardline : doc.builders.softline
] : '',
']'
], { shouldBreak: shouldBreakElements });
}function concat(parts: Doc[]): Doc[]⚠️ Deprecated: This function will be removed in v4. Use array syntax directly instead.
Legacy function that simply returns the parts array. Modern code should use arrays directly.
Example:
// Deprecated usage
const doc = doc.builders.concat([part1, part2, part3]);
// Modern equivalent
const doc = [part1, part2, part3];Install with Tessl CLI
npx tessl i tessl/npm-prettier