prettier/prettier

Prettier is an opinionated code formatter.

51,810 stars JavaScript 8 components

10 hidden assumptions · 5-stage pipeline · 8 components

Like any codebase, this cli tool makes assumptions it never checks — most are routine. The ones worth your attention are below.

Parses code, applies consistent formatting rules, and outputs reformatted text across 15+ languages

Source code enters through CLI or API, gets parsed into language-specific ASTs using registered parsers, then traversed to build an intermediate document representation using layout primitives. The document tree is finally printed to formatted text with proper indentation and line breaking based on the configured print width and style options.

Under the hood, the system uses 3 data pools, 4 control points to manage its runtime behavior.

A 8-component cli tool. 5606 files analyzed. Data flows through 5 distinct pipeline stages.

Hidden Assumptions

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

Silent failures or EACCES errors when trying to read .prettierrc files in protected directories or network-mounted filesystems with restrictive permissions

Worth your attention first

Array.at() calls with negative indices return undefined when stack is shorter than expected, causing cascading null reference errors in printer functions that rely on parent/grandparent navigation

Worth your attention first

printDocToString() processes malformed Doc objects without validation, leading to incorrect formatting output or runtime errors when accessing expected properties

Show everything (7 more)
Temporal

EditorConfig files remain unchanged between cache entries, and the cache never becomes stale during long-running processes or file watching scenarios

If this fails: Outdated formatting rules applied when .editorconfig files are modified after initial load, requiring manual cache clearing or process restart to pick up changes

src/config/editorconfig/index.js:editorconfigCache
Ordering

Built-in plugins are always loaded before user plugins in the Promise.all array, and plugin precedence follows the flat() array order

If this fails: Plugin conflicts resolved unexpectedly if user plugins override built-in parsers/printers, potentially causing wrong language detection or formatting behavior

src/index.js:withPlugins function
Scale

File contents fit in Node.js memory limits and fs.readFile can handle the entire file synchronously without streaming

If this fails: ENOMEM errors or blocking event loop when serving large JavaScript/HTML files that exceed available RAM, especially in memory-constrained environments

tests/config/browser-prettier/server.js:getContent
Domain

HTML node structures follow standard DOM patterns with expected property names (kind, children, isSelfClosing, endSourceSpan) and Vue-specific nodes are properly identified by isVueNonHtmlBlock

If this fails: Incorrectly preserved or formatted content when processing HTML from different parsers or non-standard markup structures that don't match the expected node shape

src/language-html/utilities/index.js:shouldPreserveContent
Environment

File paths are accessible and readable by the Node.js process, and glob patterns in ignore files resolve without filesystem permission errors

If this fails: getFileInfo returns incorrect 'ignored: false' status for files that should be ignored when .prettierignore files cannot be read or glob matching fails due to permissions

src/common/get-file-info.js:isIgnored call
Contract

All location utility functions receive AST nodes that conform to the expected location schema with loc, start, end properties as used by Babel/TypeScript parsers

If this fails: Location comparison and manipulation functions fail silently or return wrong results when processing AST nodes from different parsers that use alternative location formats

src/language-js/location/index.js:exports
Resource

Input text size is reasonable for string manipulation operations and the outdent template literal processing doesn't exceed stack limits

If this fails: Stack overflow or performance degradation when processing very large TOML files with deeply nested template literal operations

tests/config/prettier-plugins/prettier-plugin-dummy-toml/index.js:print function

Open the standalone hidden-assumptions report for prettier →

How Data Flows Through the System

Source code enters through CLI or API, gets parsed into language-specific ASTs using registered parsers, then traversed to build an intermediate document representation using layout primitives. The document tree is finally printed to formatted text with proper indentation and line breaking based on the configured print width and style options.

  1. Load configuration — resolveConfig() searches for .prettierrc files, merges with EditorConfig settings, and normalizeOptions() validates the final configuration object [file path → FormatOptions]
  2. Load and register plugins — loadPlugins() imports built-in and external plugins, extracting their parsers, printers, and language definitions into a global registry [plugin paths array → Plugin]
  3. Parse source code — Selected parser (babel, typescript, postcss, etc.) converts source text into language-specific AST representation using the parser function from registered plugins [source text string → AST]
  4. Build document tree — printAstToDoc() traverses AST using AstPath for context, calling language-specific print functions that return Doc builders like group(), indent(), and line to represent formatting structure [AST → Doc]
  5. Print formatted output — printDocToString() processes the document tree, making layout decisions based on printWidth, resolving groups that break or stay inline, and generating final formatted text [Doc → formatted text string]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

AST src/language-*/parsers/
Language-specific tree structures — JavaScript uses Babel/TypeScript ESTree format with type, loc, range properties; CSS uses postcss AST; HTML uses Angular parser nodes
Created by language parsers from source text, traversed by printers to build document structures, then discarded after formatting
Doc src/document/builders/index.js
Union type of string | DocArray | DocObject where DocObjects have type field ('group', 'indent', 'line', 'if-break') plus type-specific properties like contents, breakParent, expanded
Built by language-specific print functions traversing the AST, then consumed by the printer to generate final formatted text
FormatOptions src/main/normalize-format-options.js
Object with printWidth: number, tabWidth: number, useTabs: boolean, semi: boolean, singleQuote: boolean, parser: string, plugins: Plugin[], filepath?: string, and 30+ other formatting preferences
Assembled from CLI args, config files, and defaults; normalized and validated; then passed through the entire formatting pipeline
Plugin src/plugins/
Object with languages: LanguageDescriptor[], parsers: {[name]: ParserFunction}, printers: {[astFormat]: PrinterFunction}, options?: OptionDescriptor[], defaultOptions?: object
Loaded from npm packages or file paths, registered in global plugin registry, then used by core to extend language support
AstPath src/common/ast-path.js
Class with stack: any[] containing path from root to current node, plus computed properties like node, parent, key, index, siblings for AST navigation
Created during AST traversal to provide printers with context about current node's position and relationships in the tree

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

Plugin Registry (registry)
Global store of loaded plugins mapping parser names to parser functions and AST formats to printer functions
Config Cache (cache)
Caches resolved configuration objects by file path to avoid repeated filesystem searches and parsing of config files
EditorConfig Cache (cache)
Stores parsed EditorConfig settings by directory to avoid re-reading .editorconfig files for files in the same directory

Delays

Control Points

Technology Stack

Babel Parser (library)
Parses JavaScript/TypeScript code into ESTree-compatible ASTs
PostCSS (library)
Parses CSS/SCSS/Less into ASTs for the CSS formatting pipeline
Angular HTML Parser (library)
Parses HTML templates and Vue/Angular components into traversable ASTs
GraphQL (library)
Parses GraphQL schemas and queries for formatting GraphQL code
mdast (library)
Markdown AST utilities for parsing and formatting Markdown documents
fast-glob (library)
File pattern matching for CLI file discovery and ignore pattern processing
EditorConfig (library)
Reads .editorconfig files to inherit indentation and line-ending preferences

Key Components

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Compare prettier

Related Cli Tool Repositories

Frequently Asked Questions

What is prettier used for?

Parses code, applies consistent formatting rules, and outputs reformatted text across 15+ languages prettier/prettier is a 8-component cli tool written in JavaScript. Data flows through 5 distinct pipeline stages. The codebase contains 5606 files.

How is prettier architected?

prettier is organized into 6 architecture layers: CLI Interface, Configuration System, Core Formatting Engine, Language Parsers, and 2 more. Data flows through 5 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through prettier?

Data moves through 5 stages: Load configuration → Load and register plugins → Parse source code → Build document tree → Print formatted output. Source code enters through CLI or API, gets parsed into language-specific ASTs using registered parsers, then traversed to build an intermediate document representation using layout primitives. The document tree is finally printed to formatted text with proper indentation and line breaking based on the configured print width and style options. This pipeline design reflects a complex multi-stage processing system.

What technologies does prettier use?

The core stack includes Babel Parser (Parses JavaScript/TypeScript code into ESTree-compatible ASTs), PostCSS (Parses CSS/SCSS/Less into ASTs for the CSS formatting pipeline), Angular HTML Parser (Parses HTML templates and Vue/Angular components into traversable ASTs), GraphQL (Parses GraphQL schemas and queries for formatting GraphQL code), mdast (Markdown AST utilities for parsing and formatting Markdown documents), fast-glob (File pattern matching for CLI file discovery and ignore pattern processing), and 1 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does prettier have?

prettier exhibits 3 data pools (Plugin Registry, Config Cache), 4 control points, 2 delays. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does prettier use?

4 design patterns detected: Plugin Architecture, Visitor Pattern, Builder Pattern, Configuration Cascade.

How does prettier compare to alternatives?

CodeSea has side-by-side architecture comparisons of prettier with eslint. These comparisons show tech stack differences, pipeline design, system behavior, and code patterns. See the comparison pages above for detailed analysis.

Analyzed on April 20, 2026 by CodeSea. Written by .