| | |

Serialization 02 ๐Ÿ“„ Tooling, Linter Integration, and Formatting (yamlfmt, prettier, taplo)

โฑ๏ธ Estimated read: 9 min | |

Formatting tools for YAML and TOML are not interchangeable. The ecosystem has converged on a division of labor: yamlfmt and Prettier handle YAML, taplo handles TOML, and Prettier’s TOML support is a plugin that wraps taplo rather than a native implementation. Choosing the wrong tool produces inconsistent formatting, silent failures in CI, and configuration that drifts between editors. This chapter covers the three tools, their installation and usage, and the integration patterns that keep formatting enforced across a team.

The sections that follow walk through yamlfmt and its configuration options, Prettier’s YAML support and its limits, and taplo as the TOML-specific tool. Each section pairs the command with the CI pattern that makes formatting enforceable rather than advisory.

Key point: Use yamlfmt or Prettier for YAML and taplo for TOML; Prettier’s TOML support depends on a plugin that wraps taplo, so taplo is the direct dependency in either case.


Why formatting tools exist

The consistency problem. A YAML file edited by three developers will contain three indentation styles, three quoting conventions, and three opinions about whether sequences should be indented under their keys. The parser does not care; the reviewer does. A formatter removes the argument by making every file look the same, and a CI check makes the consistency enforceable rather than aspirational.

The TOML tooling gap problem. Prettier’s documentation lists YAML as a supported language, but TOML is not in Prettier’s native language set . The prettier-plugin-toml package exists, but its implementation delegates to taplo rather than parsing TOML itself . This means adding TOML to a Prettier setup adds taplo as a transitive dependency, and the formatting behavior is taplo‘s behavior regardless of the Prettier configuration.

The configuration surface problem. yamlfmt‘s defaults are opinionated in ways that surprise first-time users. The tool indents sequence items under their parent key by default, which is valid YAML but differs from the common style of leaving sequence items at the same indentation as the key. The indentless_arrays option changes this, and the retain_line_breaks option prevents the formatter from collapsing intentional blank lines . A formatter that fights the author’s style will be disabled rather than adopted.


a. yamlfmt: installation, usage, and configuration

yamlfmt is a Go-based YAML formatter maintained by Google (though the repository notes it is not officially supported by Google and is maintained by a single contributor in spare time) . It installs as a single binary with no runtime dependencies.

# Install via Go
go install github.com/google/yamlfmt/cmd/yamlfmt@latest

# Format specific files (writes to stdout)
yamlfmt file1.yaml file2.yaml

# Format in place
yamlfmt -w file1.yaml file2.yaml

# Format a directory recursively
yamlfmt .

The tool reads configuration from a .yamlfmt file in the working directory, a path passed with --conf, or a global config path. The two options that matter for most projects are indentless_arrays and retain_line_breaks .

# .yamlfmt
formatter:
  indentless_arrays: true
  retain_line_breaks: true
  scan_folded_as_literal: true

indentless_arrays: true stops the formatter from adding two spaces before sequence items under a mapping key. retain_line_breaks: true preserves blank lines the author inserted for readability. scan_folded_as_literal: true prevents the formatter from collapsing > folded blocks into single lines, which is destructive for HTML or long text blocks .

For CI, yamlfmt provides a -lint flag that exits non-zero if any file would be reformatted, and -quiet to reduce output to the file paths that differ .

# CI check: fail if formatting differs
yamlfmt -lint -quiet .

b. Prettier: YAML support and the TOML gap

Prettier formats YAML natively. Its documentation lists YAML as a supported language, and the formatter applies consistent indentation, quote style, and line wrapping to .yaml and .yml files . For teams already using Prettier for JavaScript, TypeScript, and JSON, adding YAML is a configuration change, not a new dependency.

# Format YAML with Prettier
npx prettier --write "**/*.{yaml,yml}"

# Check without writing (CI)
npx prettier --check "**/*.{yaml,yml}"

The limit is TOML. Prettier does not natively support TOML . The prettier-plugin-toml package provides TOML formatting, but it is a wrapper around taplo . A project that wants Prettier to handle both formats must install the plugin, and the plugin’s behavior is taplo‘s behavior, not Prettier’s. The practical consequence is that taplo is the TOML formatter either way; the plugin only changes how it is invoked.


c. taplo: the TOML toolkit

taplo is a TOML validator, formatter, and language server written in Rust. It is the reference implementation for TOML formatting in the JavaScript ecosystem because the Prettier plugin delegates to it . It installs via Cargo, npm, or Yarn.

# Install via npm
npm install -g @taplo/cli

# Format all TOML files in the project
npx @taplo/cli fmt

# Check formatting without writing (CI)
npx @taplo/cli fmt --check

taplo also provides a lint subcommand for validating TOML documents beyond formatting, and it supports schema validation for common configuration files like Cargo.toml and pyproject.toml . The configuration file is taplo.toml, and the formatter options include align_comments, which aligns inline comments across a block .

For pre-commit integration, taplo has an unofficial hook maintained by the community (ComPWA/taplo-pre-commit), because the main project has not published an official pre-commit hook . A project that uses pre-commit can either add the unofficial hook or run taplo fmt --check as a local hook.


Complete Example Session

# ============================================
# PART 1: PROJECT STRUCTURE
# ============================================
# project/
#   .yamlfmt           # yamlfmt configuration
#   .prettierrc        # Prettier configuration
#   taplo.toml         # taplo configuration
#   config.yaml
#   pyproject.toml

# ============================================
# PART 2: YAMLFMT CONFIGURATION
# ============================================
# .yamlfmt
formatter:
  indentless_arrays: true        # no extra indent for sequences
  retain_line_breaks: true       # keep intentional blank lines
  scan_folded_as_literal: true   # don't collapse > blocks

# ============================================
# PART 3: PRETTIER CONFIGURATION (YAML)
# ============================================
# .prettierrc
# {
#   "tabWidth": 2,
#   "singleQuote": true
# }

# ============================================
# PART 4: TAPLO CONFIGURATION
# ============================================
# taplo.toml
# [formatting]
# align_comments = true

# ============================================
# PART 5: CI COMMANDS
# ============================================
# YAML with yamlfmt
# yamlfmt -lint -quiet .

# YAML with Prettier
# npx prettier --check "**/*.{yaml,yml}"

# TOML with taplo
# npx @taplo/cli fmt --check

The parts covered the project structure, yamlfmt configuration options, Prettier YAML configuration, taplo configuration, and the CI check commands for each tool.


Quick Reference

Tool Comparison

ToolFormatsInstallationCI Flag
yamlfmtYAMLgo install or binary-lint
PrettierYAML (native), TOML (plugin)npx prettier--check
taploTOMLnpm install -g @taplo/clifmt --check

yamlfmt Configuration Options

OptionDefaultEffect
indentless_arraysfalseNo extra indent for sequence items
retain_line_breaksfalsePreserve blank lines
scan_folded_as_literalfalseDon’t collapse > blocks

Prettier TOML Dependency

AspectDetail
Native TOMLNo
Pluginprettier-plugin-toml
Underlying enginetaplo
Practical implicationtaplo is always the TOML formatter

Best Practices

โœ… Do This:

# Configure yamlfmt before adopting it
# .yamlfmt with indentless_arrays and retain_line_breaks    # โœ…

# Use taplo directly for TOML
npx @taplo/cli fmt --check                                   # โœ…

# Run formatting checks in CI
yamlfmt -lint -quiet .                                       # โœ…

# Use the same tool locally and in CI
# (avoid editor-specific formatting that CI rejects)         # โœ…

โŒ Don’t Do This:

# Assume Prettier handles TOML natively
npx prettier --check "**/*.toml"                             # โŒ (no native support)

# Use yamlfmt defaults without testing on existing files
yamlfmt -w .                                                 # โŒ (may reindent sequences)

# Run formatter in CI without checking locally first
yamlfmt . # no -lint, no -w                                   # โŒ (output only)

Common Pitfalls

PitfallWhy It HappensFix
Sequence items reindented unexpectedlyyamlfmt default behaviorSet indentless_arrays: true
Folded block collapsedDefault scan_folded_as_literal: falseSet to true
Prettier TOML check failsNo native TOML supportUse taplo or the plugin
CI passes locally but fails remotelyDifferent tool versionsPin versions in CI config
Blank lines removedretain_line_breaks not setSet to true

Real-World Examples

1. Install yamlfmt

go install github.com/google/yamlfmt/cmd/yamlfmt@latest

2. Format YAML in place

yamlfmt -w config.yaml

3. yamlfmt CI check

yamlfmt -lint -quiet .

4. Prettier YAML check

npx prettier --check "**/*.{yaml,yml}"

5. Install taplo

npm install -g @taplo/cli

6. taplo format check

npx @taplo/cli fmt --check

7. yamlfmt config file

formatter:
  indentless_arrays: true

8. taplo config file

[formatting]
align_comments = true

9. Prettier with TOML plugin

npm install -D prettier-plugin-toml

10. Docker yamlfmt

docker run -v "$(pwd):/project" ghcr.io/google/yamlfmt:latest -lint .

Visual

The Tool Landscape

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  FORMATTERS BY FORMAT                                   โ”‚
โ”‚                                                         โ”‚
โ”‚  YAML                                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                     โ”‚
โ”‚  โ”‚ yamlfmt      โ”‚  โ”‚ Prettier     โ”‚                     โ”‚
โ”‚  โ”‚ (Go, binary) โ”‚  โ”‚ (native)     โ”‚                     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚
โ”‚                                                         โ”‚
โ”‚  TOML                                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                     โ”‚
โ”‚  โ”‚ taplo        โ”‚  โ”‚ Prettier     โ”‚                     โ”‚
โ”‚  โ”‚ (Rust)       โ”‚  โ”‚ + plugin     โ”‚                     โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚
โ”‚                           โ”‚                             โ”‚
โ”‚                           โ–ผ                             โ”‚
โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                     โ”‚
โ”‚                    โ”‚ taplo engine โ”‚                     โ”‚
โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                     โ”‚
โ”‚                                                         โ”‚
โ”‚  Prettier's TOML is taplo under a plugin wrapper        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

yamlfmt’s Default Behavior

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  DEFAULT (indentless_arrays: false)                     โ”‚
โ”‚                                                         โ”‚
โ”‚  key:                                                   โ”‚
โ”‚    - item1        โ—„โ”€โ”€ extra indent added                โ”‚
โ”‚    - item2                                              โ”‚
โ”‚                                                         โ”‚
โ”‚  CONFIGURED (indentless_arrays: true)                   โ”‚
โ”‚                                                         โ”‚
โ”‚  key:                                                   โ”‚
โ”‚  - item1          โ—„โ”€โ”€ same column as key                โ”‚
โ”‚  - item2                                                โ”‚
โ”‚                                                         โ”‚
โ”‚  Both valid; the option matches common style            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

CI Integration Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  CI FORMATTING PIPELINE                                 โ”‚
โ”‚                                                         โ”‚
โ”‚  Developer commits                                      โ”‚
โ”‚         โ”‚                                               โ”‚
โ”‚         โ–ผ                                               โ”‚
โ”‚  CI runs:                                               โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚  โ”‚ yamlfmt -lint -quiet .                   โ”‚           โ”‚
โ”‚  โ”‚ npx @taplo/cli fmt --check               โ”‚           โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚         โ”‚                                               โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”                                          โ”‚
โ”‚    โ–ผ         โ–ผ                                          โ”‚
โ”‚  PASS      FAIL                                         โ”‚
โ”‚    โ”‚         โ”‚                                          โ”‚
โ”‚    โ–ผ         โ–ผ                                          โ”‚
โ”‚  Merge    Developer runs formatter                      โ”‚
โ”‚           locally, commits fix                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

yamlfmt Folded Block Behavior

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  scan_folded_as_literal: false (default)                โ”‚
โ”‚                                                         โ”‚
โ”‚  description: >                                         โ”‚
โ”‚    <table>                                              โ”‚
โ”‚    <tr><td>1</td></tr>                                  โ”‚
โ”‚    </table>                                             โ”‚
โ”‚         โ”‚                                               โ”‚
โ”‚         โ–ผ                                               โ”‚
โ”‚  Collapsed to one line (destructive)                    โ”‚
โ”‚                                                         โ”‚
โ”‚  scan_folded_as_literal: true                           โ”‚
โ”‚         โ”‚                                               โ”‚
โ”‚         โ–ผ                                               โ”‚
โ”‚  Line breaks preserved                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
YAML formatter (Go)yamlfmt
YAML formatter (JS)Prettier (native)
TOML formattertaplo
Prettier TOMLPlugin wrapping taplo
yamlfmt CI flag-lint
taplo CI flagfmt --check
yamlfmt key optionindentless_arrays
taplo config filetaplo.toml

Key takeaways:

  • The formatter ecosystem is split by format. yamlfmt and Prettier handle YAML; taplo handles TOML. Prettier’s TOML support is a plugin that delegates to taplo, so taplo is the TOML engine regardless of how it is invoked .
  • yamlfmt‘s defaults need configuration for most projects. The default sequence indentation and line-break handling differ from common style; indentless_arrays and retain_line_breaks align the formatter with the file .
  • Prettier is the right choice when the project already uses it. Adding YAML formatting to an existing Prettier setup costs a configuration change; adding TOML requires the plugin and therefore taplo.
  • CI enforcement requires a check flag. yamlfmt -lint and taplo fmt --check exit non-zero when formatting differs, turning style into a gate rather than a suggestion .
  • Pin versions across local and CI. A formatter that changed between versions will produce diffs that local development cannot reproduce, and the CI failure will be unexplainable without the version lock.

Remember: Formatting tools are only useful when they are enforced. yamlfmt and taplo both provide check flags for CI; Prettier provides --check. The configuration is secondary to the gate: a project that runs the formatter in CI with a pinned version will converge on consistency, while a project that only documents “run the formatter” will not. Choose the tool for the format, configure the options that match the team’s style, and add the check to CI before adding the formatter to the editor.

Was this helpful?


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!