Programming

Prettier XML Formatting: Inline/Block Elements & Whitespace

Learn how to format XML with Prettier XML plugin, handling inline vs block elements correctly. Preserve whitespace using xmlWhitespaceSensitivity, prettier-ignore, xml:space, and CI-ready alternatives like xml-formatter or xmllint.

1 answer 1 view

How to format XML files with Prettier XML plugin handling inline and block elements correctly? Prettier does not distinguish block vs inline elements, causing odd formatting. Is there a CI-ready solution or better alternative to specify block/inline elements and preserve whitespace?

Prettier’s XML plugin doesn’t have built‑in knowledge of “inline” vs “block” elements, so you’ll see short tags split across lines or odd indentation when formatting XML with Prettier XML plugin. You can reduce the pain by setting xmlWhitespaceSensitivity to "preserve", using <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> around problem nodes, or marking inline nodes with xml:space="preserve" and running an XML-aware formatter (or classic tools like xmllint/xmlstarlet) in your CI pipeline. For strict inline/block control the practical choices are: preprocess to tag inline elements, use a dedicated XML formatter that respects xml:space (for example the xml-formatter package), or write a small custom Prettier plugin — the last two are the most reliable for CI.


Contents


Prettier XML plugin options for XML format and whitespace

Prettier’s XML plugin treats tags uniformly; it doesn’t have a notion of “this element is inline” versus “this is a block element.” See the plugin repo for details and the available options: the plugin exposes an xmlWhitespaceSensitivity setting with values like "strict", "ignore", and "preserve" that change how whitespace is handled during formatting (prettier/plugin-xml, npm: @prettier/plugin-xml). There’s an active discussion about preserving significant whitespace in XML in issue #478 — worth reading if you need fine-grained behavior: https://github.com/prettier/plugin-xml/issues/478.

Example .prettierrc (project root):

json
{
 "plugins": ["@prettier/plugin-xml"],
 "xmlWhitespaceSensitivity": "preserve",
 "printWidth": 100
}

CLI (format all XML files):

bash
npx prettier --plugin=@prettier/plugin-xml --write "**/*.xml"
# or the explicit binary:
./node_modules/.bin/prettier --plugin=@prettier/plugin-xml --write "**/*.xml"

If you set xmlWhitespaceSensitivity to "preserve", Prettier will avoid normalizing text-node whitespace, which helps when whitespace inside an element is significant. But note: even with preserve, Prettier still decides line breaks and indentation based on its generic rules — it won’t automatically keep specified tags inline. For that you need a different technique.


Practical workarounds: xml:space and prettier-ignore

Want to keep particular nodes exactly as authored? Two practical workarounds work well in real projects.

  1. Mark elements that must keep their internal spacing with xml:space="preserve". The XML spec and common parsers recognize this attribute as the canonical way to indicate that whitespace inside this element is significant. See background on xml:space and whitespace handling: http://usingxml.com/Basics/XmlSpace, https://www.tutorialspoint.com/xml/xml_white_spaces.htm and Oracle’s overview https://www.oracle.com/technical-resources/articles/wang-whitespace.html.

Example:

xml
<description xml:space="preserve"> This is significant spacing. </description>

A formatter that respects xml:space will keep that internal spacing intact. The xml-formatter NPM package is one such tool that explicitly respects xml:space and can be used as an alternative to Prettier for XML formatting: https://www.npmjs.com/package/xml-formatter.

  1. Use Prettier ignore comments around problem nodes when you only have a few exceptions. Prettier supports <!-- prettier-ignore-start --> / <!-- prettier-ignore-end --> in XML; wrap the section you don’t want Prettier to touch.
xml
<!-- prettier-ignore-start -->
<inline><b> exact spacing </b></inline>
<!-- prettier-ignore-end -->

Caveats: prettier-ignore leaves raw content in the repo (manual markers add noise), and adding xml:space changes the XML to include metadata — acceptable in many schemas, but check compatibility first.

If you have many inline elements, automate adding xml:space="preserve" before formatting via a small preprocessing script (XSLT, xmlstarlet, or a short Node script that parses and updates attributes), then run your formatter. That way the source is consistently annotated and CI-friendly.


CI-ready Prettier workflow (checks and autoformat)

You can make XML formatting part of CI either with Prettier (best for teams already standardizing on Prettier) or with XML-specific tools.

Prettier-based CI (fast, consistent with JS/HTML formatting steps):

  • Add @prettier/plugin-xml to devDependencies.
  • Add scripts to package.json:
json
{
 "scripts": {
 "format:xml": "prettier --plugin=@prettier/plugin-xml --write \"**/*.xml\"",
 "check:xml": "prettier --plugin=@prettier/plugin-xml --check \"**/*.xml\""
 }
}
  • GitHub Actions job (example):
yaml
name: Check XML formatting
on: [push, pull_request]
jobs:
 xml-format:
 runs-on: ubuntu-latest
 steps:
 - uses: actions/checkout@v3
 - uses: actions/setup-node@v4
 with: { node-version: 18 }
 - run: npm ci
 - run: npm run check:xml

If Prettier can’t express the inline/block policy you need, replace or augment the check with an XML-specific formatter or validator.

XML-tooling CI (deterministic formatting or validation):

  • Use xmllint or xmlstarlet to pretty-print and compare. These classic tools are easy to install on CI runners and scale to large files; see practical CI tips: https://encode64.com/en/minifiers/xml-minifier.
  • Example quick check (bash):
bash
# format to a temp file and diff
xmllint --format file.xml > file.formatted.xml
if ! diff -q file.xml file.formatted.xml; then
 echo "file.xml is not formatted"
 exit 1
fi

This approach gives you deterministic XML-only behavior and avoids fighting Prettier’s generic tag wrapping.


Alternatives: XML formatter tools that respect xml:space and inline/block elements

If you need precise control over how inline tags are kept on one line or block-level tags are expanded, consider dedicated XML formatters rather than Prettier.

If none of these meet your exact inline/block rule needs, you can write a small formatter/script that:

  • Parses XML,
  • Maps a configured list of inline tags,
  • Emits those inline tags on a single line (or sets xml:space="preserve"),
  • Then runs an XML pretty-printer for the rest.

That gives you full control without rewriting a Prettier printer.


How to pick the right approach (tradeoffs & quick recipes)

Which route should you take? Quick decision guide:

  • You want minimal changes and already use Prettier across the repo:

  • Try xmlWhitespaceSensitivity: "preserve" + prettier-ignore for a few spots.

  • Add check:xml and format:xml scripts and enforce them in CI.

  • You need consistent, project-wide inline/block rules (many inline tags):

  • Add xml:space="preserve" to those tags automatically (preprocess) and use an XML-aware formatter (or xmllint) in CI.

  • Or choose a dedicated formatter like xml-formatter and run it in CI and pre-commit hooks.

  • You need exact, deterministic output (e.g., for generated config files or tests):

  • Use classic tools (xmllint/xmlstarlet) or a dedicated XML formatter in CI. Don’t rely on Prettier for this level of control.

A sample practical recipe I use often:

  1. Maintain a JSON list of inline tags in repo (e.g., [“b”,“i”,“code”,“abbr”]).
  2. Run a small Node script that adds xml:space="preserve" to those tags (idempotent).
  3. Run xml-formatter (or xmllint) to pretty-print.
  4. Commit formatted files; enforce with a CI prettier --check or node format-check.js.

That keeps behavior deterministic, CI-friendly, and avoids littering the source with prettier-ignore comments.


Sources

  1. https://github.com/prettier/plugin-xml
  2. https://github.com/prettier/plugin-xml/issues/478
  3. https://jsonformatter.org/xml-formatter
  4. https://onlinexmltools.com/prettify-xml
  5. https://www.npmjs.com/package/@prettier/plugin-xml
  6. https://salesforce.stackexchange.com/questions/415949/how-can-i-get-prettier-to-properly-format-perm-set-xml-files-with-flowaccess
  7. https://www.freecodecamp.org/news/alternatives-to-prettier/
  8. https://dev.to/withtoms/prettier-and-how-to-get-most-out-of-it-2d46
  9. http://usingxml.com/Basics/XmlSpace
  10. https://www.oracle.com/technical-resources/articles/wang-whitespace.html
  11. https://encode64.com/en/minifiers/xml-minifier
  12. https://www.npmjs.com/package/xml-formatter
  13. https://www.tutorialspoint.com/xml/xml_white_spaces.htm

Conclusion

Prettier XML plugin is convenient but won’t natively honor inline vs block semantics — that’s why short inline tags can look wrong after formatting. For CI-ready XML format control, either (a) use the plugin with xmlWhitespaceSensitivity: "preserve" plus targeted prettier-ignore and xml:space="preserve" annotations, or (b) switch to an XML-aware formatter (like xml-formatter) or classic tools (xmllint/xmlstarlet) run from CI. If you need full, deterministic inline/block rules, preprocess tags or use a dedicated XML formatter (or build a custom Prettier plugin) — the result is predictable XML format that preserves whitespace the way you expect.

Authors
Verified by moderation
Moderation
Prettier XML Formatting: Inline/Block Elements & Whitespace