prettier/prettier
Prettier is an opinionated code formatter.
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".
Silent failures or EACCES errors when trying to read .prettierrc files in protected directories or network-mounted filesystems with restrictive permissions
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
printDocToString() processes malformed Doc objects without validation, leading to incorrect formatting output or runtime errors when accessing expected properties
Show everything (7 more)
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
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
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
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
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
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
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.
- Load configuration — resolveConfig() searches for .prettierrc files, merges with EditorConfig settings, and normalizeOptions() validates the final configuration object [file path → FormatOptions]
- 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]
- 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]
- 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]
- 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.
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
src/document/builders/index.jsUnion 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
src/main/normalize-format-options.jsObject 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
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
src/common/ast-path.jsClass 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
Global store of loaded plugins mapping parser names to parser functions and AST formats to printer functions
Caches resolved configuration objects by file path to avoid repeated filesystem searches and parsing of config files
Stores parsed EditorConfig settings by directory to avoid re-reading .editorconfig files for files in the same directory
Delays
- Plugin loading (async-processing, ~startup time) — Dynamic imports of plugin modules and their dependencies must resolve before parsing can begin
- Config file search (async-processing, ~filesystem scan) — Walks up directory tree to find .prettierrc files, can be slow on deep directory structures
Control Points
- printWidth (threshold) — Controls: Line length limit that determines when groups break to multiple lines. Default: 80
- parser (architecture-switch) — Controls: Which language parser to use (babel, typescript, postcss, etc.) affecting AST structure and available formatting features. Default: inferred from file extension
- plugins (architecture-switch) — Controls: Which language plugins are loaded, determining supported file types and parsing capabilities. Default: built-in plugins + user specified
- singleQuote (feature-flag) — Controls: Whether to prefer single quotes over double quotes in string literals. Default: false
Technology Stack
Parses JavaScript/TypeScript code into ESTree-compatible ASTs
Parses CSS/SCSS/Less into ASTs for the CSS formatting pipeline
Parses HTML templates and Vue/Angular components into traversable ASTs
Parses GraphQL schemas and queries for formatting GraphQL code
Markdown AST utilities for parsing and formatting Markdown documents
File pattern matching for CLI file discovery and ignore pattern processing
Reads .editorconfig files to inherit indentation and line-ending preferences
Key Components
- format (orchestrator) — Main formatting function that coordinates the entire pipeline — loads plugins, parses options, calls language-specific parsers and printers
src/main/core.js - AstPath (adapter) — Provides navigation interface for AST traversal with properties like node, parent, key, index to help printers understand context
src/common/ast-path.js - printAstToDoc (transformer) — Converts AST to intermediate document representation by calling language-specific print functions with AstPath context
src/main/core.js - printDocToString (processor) — Final stage that converts document tree into formatted text string, handling line breaks, indentation, and group layout decisions
src/document/printer/printer.js - resolveConfig (resolver) — Searches filesystem for prettier config files (.prettierrc, prettier.config.js) and merges them with EditorConfig and defaults
src/config/resolve-config.js - loadPlugins (loader) — Dynamically imports and registers plugins from npm packages or file paths, building the global plugin registry
src/main/plugins/index.js - getFileInfo (resolver) — Determines if a file should be ignored and infers the appropriate parser based on file extension and content
src/common/get-file-info.js - normalizeOptions (validator) — Validates and normalizes user-provided options, applying defaults and type conversions for all formatting preferences
src/main/normalize-options.js
Explore the interactive analysis
See the full architecture map, data flow, and code patterns visualization.
Analyze on CodeSeaCompare 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 Karolina Sarna.