A Detailed Comparison of YAML Formatters
This is a survey of the current state of YAML formatters. For this blog post, I’m comparing tools that take YAML files on disk and rewrite them to some standard. This is beyond the scope of a normal YAML linter.
If you ask me, all file formats deserve a fmt
tool.
YAML is not exception, especially as it is not the best.
In fact there is even StrictYAML
with features removed.
This isn’t quite a fmt
tool, but limiting the craziness you can put in a YAML file certainly makes it easier to format!
After looking these formatters, I think they still do not go far enough.
None of them block the Norway problem.
All of them (except Prettier) turn multiline complexity into multiline insanity.
Maybe someday I’ll write my own YAML formatter, probably based on StrictYAML
, that blocks nonsense and homogenizes everything.
Till then, if I missed a linter or missed a feature you are interested in, just [email me](kyle@xkyle.com?subject=YAML Formatters). Or better yet make a pull request on the code I used.
The List
- Google (unofficial) yamlfmt: Standalone tool for formatting YAML
- pre-commit-hook-yamlfmtl: a hook for the pre-commit system
- Python yamlfmt: A CLI wrapper around the python ruamel.yaml library
- Prettier: A general purpose formatting tool for many languages
And here is a TLDR summary of the results given default settings:
Formatter | Google yamlfmt | Pre-commit yamlfmt | Python yamlfmt | Prettier |
---|---|---|---|---|
Language | golang | python | python | nodejs |
Preserves anchors | Yes (adds explicit !!merge ) |
Yes (misplaces comment) | Yes (misplaces comment) | Yes |
Homogenizes horizontal whitespace | Yes (removed blank newlines) | No | No | No |
Homogenizes indents? | Defaults to 2 spaces | Defaults to 4 spaces | Preserves original | 2 spaces |
Multiline strings? (already insane) | Converts newlines to \n unless using > |
Adds " and escapes with \" |
Adds " and escapes with \" |
Preserves |
--- Header? |
Removes it | Adds it | Removes it | Preserves it |
!!TYPE explicit types |
Preserves | Removes | Removes | Preserves |
None of the formatters had features I wanted:
- Homogenize bools (no more
NO
s) - Normalize nulls (no more emptiness being null or
~
) - Normalize date formats
- Normalize floats
- Normalize hex strings
I guess I mostly want something that morphs YAML’s leniency into whatever JSON has as its final representation.
Input
See the input file here. I tried to add as many weird things in there as possible, to exercise the formatters to their maximum.
Results
Google yamlfmt
Google yamlfmt produced some of them most opinionated outputs, but is also the most configurable.
It has the potential to be the formatter I want, I think it just needs a special kyle
formatter instead of the basic one :).
Still, the fact that it removes horizontal whitespace seems weird to me (Defaults with retain_line_breaks: false
).
I think line breaks should be preserved, but multiple line breaks should be normalized to 1 (Prettier’s behavior).
There is also something to be said about a golang tool that can be installed via a binary. I appreciate that the Google yamlfmt tool doesn’t impose installing … anything except itself (no npm, node, python, etc).
Pre-commit yamlfmt
The Pre-commit yamlfmt tool is designed to be used with the pre-commit ecosystem, but it can be used in a standalone way. It has some configuration, with the current defaults:
mapping: 4 spaces
sequence: 6 spaces
offset: 4 spaces
colons: do not align top-level colons
width: None (use ruamel default)
Python yamlfmt
This standalone python script has no configuration. In some sense it is the most opinionated tool! Yet in a different way, it did the least actual formatting.
Prettier
Prettier is a general purpose formatting tool. If your needs extend past YAML and include other formats, it may be worth it to just use one tool (Prettier), if you don’t mind install node/npm.
Prettier is also very opinionated (very few options), and it does impose some of those opinions.
Conclusion
My preference is for google yamlfmt. After working with Python professionally, I’m tired of fighting Python interpreters and pip. I also lost little faith after these python yaml code execution vulnerabilities. (Ruby is not immune) I do appreciate Prettier. If you need to format lots of different stuff in one project, it might be easier to let prettier do it all.
YAML is in a weird position where it’s desire to be human-friendly leads to weirdness. Its flexibility is its downside, and its not opinionated enough in the right places to prevent more mistakes.
Till then, as with all file formats, I’m happy for any computer-enforced style guide (aka a fmt
tool).
I hope this review inspires you to adopt one, any one.