Formatter
Purpose and Scope
Biome’s formatter is the public tool that rewrites source text into Biome’s chosen style. The official formatter documentation presents it as an opinionated formatter for multiple languages, with a philosophy close to Prettier: keep the option surface small, avoid team-level style debates, and make formatting a reliable mechanical step. For users, the important mental model is that formatting is not a linter rule and not a collection of style plugins. It is a language-aware printer that takes parsed syntax and emits stable text according to a limited set of global and language-specific options.
The repository evidence on this page focuses on the CSS formatter implementation family. That is a useful representative slice because the CSS formatter is organized as a generated module tree that mirrors the CSS syntax model: “any” nodes, auxiliary nodes, list nodes, bogus recovery nodes, properties, pseudo constructs, selectors, statements, and values. The generated index files do not show every formatting algorithm, but they do show the breadth of CSS syntax that the formatter is prepared to dispatch across. Sources: crates/biome_css_formatter/src/css/mod.rs, crates/biome_css_formatter/src/css/any/mod.rs
When using the formatter from the command line, the public workflow is intentionally simple. The official docs show biome format ./src to check formatting and emit textual differences, then biome format --write ./src to apply the result. The command accepts files and directories. In a team, the configuration file is usually preferred over one-off CLI flags because the same options must be observed by both the CLI and editor integration. The implementation-side lesson from the CSS module layout is that this public simplicity sits above many language-specific syntax cases that are hidden from the user.
Relevant Source Files
crates/biome_css_formatter/src/css/mod.rs- Top-level generated CSS formatter module index that wires the major CSS formatter families together.crates/biome_css_formatter/src/css/any/mod.rs- Generated index for formatter modules that handle broad CSS syntax node categories such as at-rules, declarations, selectors, media queries, supports conditions, keyframes, and roots.crates/biome_css_formatter/src/css/auxiliary/mod.rs- Generated index for helper and composite CSS formatter modules, including declaration blocks, functions, media/query structures, imports, keyframes, and nested qualified rules.crates/biome_css_formatter/src/css/bogus/mod.rs- Generated index for formatter modules that handle erroneous or recovery syntax nodes without making the formatter collapse on malformed CSS.crates/biome_css_formatter/src/css/lists/mod.rs- Generated index for list-formatting modules, including declaration lists, selector lists, parameter lists, media query lists, and root item lists.crates/biome_css_formatter/src/css/properties/mod.rs- Generated index for CSS property formatter modules, including generic properties,composes, and value at-rule generic properties.
Public Formatting Workflow
The formatter’s public contract starts with a list of input paths and a decision about whether to report or write changes. In check mode, Biome reads the target files, formats the supported documents, and reports differences when the existing text does not match the printer output. With --write, the formatted result is applied back to disk. This separation matters because it lets developers use the same formatter in local editing, pre-commit workflows, and continuous integration, while choosing between verification and mutation depending on the context.
The official formatter options also define an important boundary: Biome separates language-agnostic options from language-specific options. Global formatter settings include concepts such as whether formatting is enabled, whether formatting may proceed with syntax errors, indentation style and width, line width, line endings, and attribute positioning. Language-specific settings then tune behavior where syntax requires it. The CSS formatter files shown here are not configuration files, but their module names demonstrate why language-specific handling exists: CSS declarations, selectors, functions, media queries, container queries, keyframes, and property values all need dedicated syntax-aware treatment.
A practical first run can look like this:
npx @biomejs/biome format ./src
npx @biomejs/biome format --write ./srcThese commands are deliberately smaller than the implementation surface. The user does not choose a different formatter for selectors, declaration lists, media queries, or keyframes. Instead, Biome selects the correct language formatter for each supported file, and that formatter dispatches internally across generated modules. In CSS, the top-level generated module index exposes the formatter families that participate in that dispatch. Sources: crates/biome_css_formatter/src/css/mod.rs, crates/biome_css_formatter/src/css/lists/mod.rs
System-to-Code Mapping
The CSS formatter module tree begins at css/mod.rs, which declares the major submodules: any, auxiliary, bogus, lists, properties, plus additional families for pseudo, selectors, statements, and values. This index is generated, and its header tells contributors not to modify it by hand but to run cargo codegen formatter when regeneration is required. That instruction is a strong signal about Biome’s formatter architecture: formatting coverage is derived from the language syntax model and code generation keeps the module wiring synchronized with grammar-level changes. Sources: crates/biome_css_formatter/src/css/mod.rs
The any family is the broadest dispatch layer visible in the supplied evidence. It includes modules for at-rules, attribute names and matchers, container queries, declaration blocks, dimensions, document matchers, functions, imports, keyframes, layers, media conditions, namespace prefixes and URLs, page selectors, properties, pseudo-classes and pseudo-elements, query features, roots, rules, selectors, supports conditions, syntax components, and Unicode values. This breadth is useful for readers because it clarifies that CSS formatting is not just whitespace around braces; it spans modern CSS constructs and nested conditional structures. Sources: crates/biome_css_formatter/src/css/any/mod.rs
The auxiliary family holds composite forms and helper syntax nodes that are not simply top-level categories. Its modules include declaration-with-semicolon, empty declarations, comma-separated values, binary expressions, parenthesized expressions, media and container query forms, @import layers and supports conditions, keyframes scoped names, function parameters and defaults, namespace handling, query feature ranges, and qualified rules. In practice, these modules let the formatter decompose complicated CSS syntax into reusable formatting responsibilities instead of treating an entire rule body as one opaque string. Sources: crates/biome_css_formatter/src/css/auxiliary/mod.rs
The lists family is the formatter’s explicit home for repeated syntax. CSS has many sequences where separators, line breaks, indentation, and trailing structure must be handled consistently: selector lists, declaration lists, function parameter lists, media query lists, layer references, keyframes selectors, component values, and root items. By giving lists their own generated modules, Biome can apply stable list formatting decisions across syntax forms while still allowing each list type to account for its own separators and surrounding grammar. Sources: crates/biome_css_formatter/src/css/lists/mod.rs
Implementation Details and Error Recovery
The presence of a generated bogus formatter family is important for both users and contributors. “Bogus” nodes are recovery nodes produced when the parser has encountered invalid or incomplete syntax but still builds a tree. The CSS formatter indexes bogus at-rules, bogus blocks, bogus selectors, bogus properties, bogus property values, bogus media queries, bogus supports conditions, bogus syntax components, bogus Unicode ranges, and related recovery forms. This does not mean malformed CSS is considered correct; it means the formatter has named code paths for preserving or traversing erroneous structures safely. Sources: crates/biome_css_formatter/src/css/bogus/mod.rs
That recovery design connects to the user-facing formatWithErrors option described in the official docs. When formatting with errors is disabled, users should expect syntax problems to block normal formatting. When it is enabled, the formatter still needs implementation support for damaged syntax so it can produce useful output without panicking or discarding content. The CSS bogus module index is the source-backed evidence for that implementation posture: parser recovery is not an afterthought, but an explicit part of the formatter module taxonomy.
Properties are also separated from the more general CSS syntax families. The supplied property index lists modules for composes_property, generic_property, and value_at_rule_generic_property. This separation reflects CSS’s shape: declarations and at-rules often contain names and values that are structurally different from selectors or query conditions. For contributors, property modules are the place to look when formatting behavior concerns property-like constructs rather than the surrounding rule, block, or list. Sources: crates/biome_css_formatter/src/css/properties/mod.rs
Every supplied CSS formatter index begins with the same generated-file warning. That warning changes the contribution workflow. Instead of hand-editing these module indexes, contributors should update the underlying formatter definitions or syntax generation inputs and then run the formatter code generation task named in the header. This protects the module graph from manual drift. It also means review comments on these files should usually focus on whether generated coverage changed as expected, not on local style edits to the index file itself. Sources: crates/biome_css_formatter/src/css/any/mod.rs, crates/biome_css_formatter/src/css/auxiliary/mod.rs, crates/biome_css_formatter/src/css/lists/mod.rs
Option Philosophy and Prettier Compatibility
Biome’s formatter option philosophy is intentionally conservative. The official option philosophy page says Biome is its own automatic style guide and follows a Prettier-like stance on resisting new formatting options. The repository evidence shown here supports that model indirectly: CSS formatting is implemented as a broad generated syntax printer rather than as a user-configurable collection of micro-style switches. The formatter must know about many CSS constructs, but users are not expected to make per-node decisions for every at-rule, selector, query, or declaration shape.
Compatibility with Prettier is a product goal, but not a promise that every byte of output will match. The official differences page documents cases where Biome intentionally diverges, especially when consistency or modern language semantics justify a different result. For CSS, the supplied source evidence does not include Prettier comparison logic, so the useful takeaway is architectural rather than behavioral: when Biome differs from another formatter, that decision should be implemented in the language formatter’s syntax-aware code paths, not patched at the command boundary.
This distinction helps teams evaluate formatting changes. If a CSS file formats differently after an upgrade, the likely cause is a language formatter change, a parser/syntax model change, an option default, or code generation reflecting new syntax coverage. The module tree gives contributors a navigation map for that investigation: start at the top-level CSS module index, identify whether the construct is an any, auxiliary, list, property, or bogus case, then inspect the generated formatter implementation behind that module. Sources: crates/biome_css_formatter/src/css/mod.rs, crates/biome_css_formatter/src/css/properties/mod.rs
Contributor and User Next Steps
Users should start with the CLI workflow from the official formatter guide: run biome format on a target directory, inspect the diff, then add --write when ready. Put shared formatter options in biome.json so command-line usage and editor integration agree. If a formatting result is surprising, reduce the example to the smallest supported file and identify whether the issue is a formatter preference, a syntax error, or a known compatibility difference with Prettier.
Contributors working on CSS formatting should treat the files listed here as generated navigation points. Use crates/biome_css_formatter/src/css/mod.rs to find the relevant family, then narrow the investigation through any, auxiliary, lists, properties, or bogus according to the syntax involved. When the change affects generated wiring, follow the header instruction and regenerate through cargo codegen formatter rather than editing the module index by hand. That keeps the formatter aligned with Biome’s syntax model and preserves the public promise of stable, language-aware formatting.