cargo dprint 0.55.0

6 hours ago

dprint is a pluggable and configurable code formatting platform that unifies all your formatters.

This substantial release adds npm specifier plugins, brings dprint to many more CPU architectures, adds richer LSP support, and gives you finer-grained configuration with per-file overrides and config inheritance.

It includes two behaviour changes worth reading before you upgrade.

Highlights

  • πŸ“¦ npm specifier plugins β€” reference plugins with npm:@scope/name@version
  • πŸ—οΈ Runs on many more architectures β€” Windows on ARM, Android (Termux), ppc64le, and LoongArch
  • πŸ’‘ LSP completions & hover for dprint configuration files
  • πŸ”€ dprint fmt --dirty β€” format only the files with uncommitted git changes
  • πŸŽ›οΈ Per-file plugin config overrides β€” apply different plugin options to specific files
  • 🧬 "inherit": true for nested configuration files
  • ⚠️ Plugin associations are now additive (behaviour change)
  • ⚠️ Globs are now case-sensitive (behaviour change)

We also have a new website: https://dprint.dev

npm specifier plugins

You can now reference plugins via an npm: specifier in your config:

{
  "plugins": [
    "npm:@dprint/typescript@0.95.15",
    "npm:@dprint/json"
  ]
}
  • Pinned form (npm:@scope/name@version) downloads and locks an exact version.
  • Omitting the version (npm:@scope/name) resolves the plugin from node_modules, walking up from the config file so npm and your lockfile stay the source of truth.
  • dprint add npm:@scope/name resolves the latest version and writes the pinned form, unless the package is in a nearby package.json under devDependencies, in which case the unversioned form is written, in which case node resolution will occur.

More architectures supported

dprint now runs on a much wider range of CPU architectures, including:

  • Windows on ARM (aarch64-pc-windows-msvc) - Now nativeβ€”previously dprint was shipping the x64 binary.
  • Android / Termux.
  • ppc64le.
  • LoongArch (now able to run plugins).

This is made possible by migrating the Wasm plugin runtime from Wasmer to Wasmtime, with equivalent performance and a smaller dependency tree:

  • Native Cranelift codegen on x86_64, aarch64, riscv64, and s390x.
  • ppc64le, LoongArch, and Android compile to Wasmtime's portable Pulley bytecode (pure Rust, no native backend, no signal-based traps β€” which the Android sandbox doesn't allow), replacing the previous wasmi interpreter path.

LSP completions and hover for config files

dprint lsp now provides autocompletion and hover documentation when editing dprint.json / dprint.jsonc, making it easier to discover plugins and configuration options without leaving your editor.

dprint fmt --dirty

Format only the files with uncommitted changes in your git working directory β€” staged, unstaged, and untracked (but not gitignored):

dprint fmt --dirty

This complements the existing --staged flag.

"inherit": true for nested config files

A nested configuration file can now opt in to inheriting its ancestor's plugins and configuration. Given a config at the repo root:

// ./dprint.json
{
  "typescript": {
    "indentWidth": 4
  },
  "plugins": [
    "https://plugins.dprint.dev/typescript-0.96.1.wasm"
  ]
}

A config in a subdirectory can inherit it with "inherit": true:

// ./sub-project/dprint.json
{
  "inherit": true,
  "typescript": {
    // inherits the ancestor's TypeScript config, but overrides the indent width
    "indentWidth": 2
  }
}
  • Plugins in the nested config take precedence; any not specified are inherited.
  • The ancestor's includes are not inherited.
  • Inheriting is opt-in so that adding a config higher in the tree doesn't unexpectedly start affecting nested configs.

Per-file plugin config overrides

Plugins now support "overrides" blocks to apply different configuration to specific files:

{
  "json": {
    "overrides": {
      "files": ["**/package.json", "**/composer.json"],
      "indentWidth": 4
    }
  }
}

Use an array for multiple overrides:

{
  "json": {
    "overrides": [
      {
        "files": ["**/package.json", "**/composer.json"],
        "indentWidth": 4
      },
      {
        "files": "**/special-package.json",
        "lineWidth": 80
      }
    ]
  }
}

Overrides are honoured consistently across CLI formatting, stdin, the editor service, the LSP, and host formatting. Note that overrides only change configuration β€” they don't include or exclude files.

⚠️ Plugin associations are now additive (behaviour change)

Previously, adding an "associations" glob to a plugin silently replaced the file extensions and file names it matched by default. Now associations are additive:

  • A positive glob (e.g. **/*.foo) routes extra files to the plugin while its defaults keep matching.
  • A negated glob (e.g. !**/*.js) cancels a default extension, file name, or path.

If you previously relied on a positive association to replace the defaults, add a negated glob to opt back out. Fixes the surprising behaviour in #841 and #794.

⚠️ Globs are now case-sensitive (behaviour change)

File pattern matching for includes/excludes globs is now case-sensitive (#1082). If your patterns relied on case-insensitive matching, update them to match the actual file casing.

Read a list of files from stdin

The new --stdin-files flag reads a newline-separated list of file paths from stdin instead of from the command line arguments. It works with the fmt, check, file-paths, and format-times subcommands, which is handy when piping the output of another tool into dprint:

generate_files | dprint fmt --stdin-files

Smarter dprint init

dprint init now scans the current directory and pre-selects the plugins whose files it finds, so the defaults match your project out of the box. The plugin picker scrolls to fit your terminal and supports type-to-filter, keeping it usable even when many plugins are available.

Pass --yes (-y) to skip the prompt entirely and accept those defaults β€” handy for scripts and CI:

dprint init --yes

The prompt is also skipped automatically when there's no interactive terminal.

Other notable additions

  • DPRINT_GLOBAL_GITIGNORE=1 β€” opt in to respecting git's global excludes file (core.excludesFile). Opt-in because it's machine-specific and won't exist on CI.
  • NO_COLOR / FORCE_COLOR support for controlling colored output.
  • dprint config update --dry-run β€” preview config updates without writing.
  • dprint resolved-config --file <path> β€” show only the plugins that would format a given file.
  • dprint incremental-state β€” print the exact signal dprint uses to decide cache reuse, so you can diff it between revisions.
  • Shorter subcommand names β€” output-resolved-config, output-file-paths, and output-format-times are now resolved-config, file-paths, and format-times.

Changelog

Features

  • feat(BREAKING): make plugin associations additive to default file matching (#1172)
  • feat(BREAKING): make globs case sensitive (#1089)
  • feat: migrate wasm plugin runtime from wasmer to wasmtime (#1178)
  • feat: add Windows on ARM (aarch64-pc-windows-msvc) builds (#1179)
  • feat: add android (Termux) builds using the wasmi interpreter backend (#1175)
  • feat: add ppc64le builds using the wasmi interpreter backend (#1174)
  • feat: use LLVM backend for LoongArch to support plugins (#1109)
  • feat: LSP completions and hover for dprint configuration files (#1177)
  • feat: support resolving plugins via npm specifiers and node resolution (#1134)
  • feat: add --dirty flag to format git working directory changes (#1171)
  • feat: add per-file plugin config overrides (#1136)
  • feat: support "inherit": true in nested configuration files (#1160)
  • feat: opt-in support for git's global excludes file via DPRINT_GLOBAL_GITIGNORE (#1163)
  • feat: support reading a list of files to format from stdin (#1157)
  • feat: support NO_COLOR and FORCE_COLOR env vars (#1155)
  • feat: add --dry-run to dprint config update (#1156)
  • feat: add --file flag to resolved-config to filter plugins by file (#1167)
  • feat: add dprint incremental-state command (#1149)
  • feat: drop output- from some subcommands (#1150)
  • feat(npm): detect plugin kind on dprint add when no path is given (#1183)
  • feat(npm): add --checksum flag to dprint add (#1184)
  • feat(init): pre-select plugins from the current directory, scrollable/filterable picker, and --yes flag (#1185)
  • feat(init): scaffold plugin config from info.json (defaultConfig + configItems) (#1186)
  • feat(init): prioritize plugin pre-selection and surface it in the list
    (#1187)

Performance

  • perf: reduce wasm plugin thread stack size to 4 MiB (#1180)
  • perf: read directories on multiple threads when globbing (#1168)
  • perf(windows): delay load DLLs not needed at startup (#1164)
  • perf: cache resolved global gitignore path to avoid repeated git subprocess (#1165)
  • perf: use similar for LSP diffing and drop dissimilar (#1176)

Bug Fixes

  • fix: normalize LSP formatted line endings to match the editor document (#1173)
  • fix: avoid hang waiting for killed process plugins in clear-cache (#1169)
  • fix: kill process plugins when running dprint clear-cache (#1154)
  • fix(npm): download binary when optional dependency is omitted (#1161)
  • fix(npm): improve musl detection (#1145)
  • fix: recompile Wasm plugin from source when loading from cache fails (#1158)
  • fix: avoid regex size limit when given many literal file paths (#1153)
  • fix: read .git/info/exclude when respecting gitignore (#1151)
  • fix(plugins): surface plugin cache cleanup errors instead of swallowing them (#1148)
  • fix(core): prevent unbounded re-evaluation when conditions oscillate (#1137)
  • fix: include plugin's resolved config in incremental cache key (#1138)
  • fix(install.sh): correct riscv64 build name, add loongarch64 support, Windows .exe path, resolve relative DPRINT_INSTALL (#1131)

Internal

  • refactor: redesign plugin cache as flat per-plugin sidecars (#1181)

Install

Run dprint upgrade or see https://dprint.dev/install/

Checksums

Artifact SHA-256 Checksum
dprint-x86_64-apple-darwin.zip 69d032d8fe70441fc4307cdd5360d5e0086773bb2f7ba63d4863e59c64f3df38
dprint-aarch64-apple-darwin.zip cf6c0149ac9ed76aee2535d0dfeffd2c9d34bcfe42c397127bba4a8c934722cc
dprint-x86_64-pc-windows-msvc.zip 44a025c8ca4cf5d9598349e48927a35186caac893fee0a5bb28e98996ef11432
dprint-x86_64-pc-windows-msvc-installer.exe e300ccdae294806c655a6949caafc3aaadabc9655ec2304e3582474ff30ff6cb
dprint-aarch64-pc-windows-msvc.zip 9ec07135b34ab20431c99994cdbdaf6f2826e2f0406f3d9d839c85571d636cd8
dprint-x86_64-unknown-linux-gnu.zip d6c2f65f8a2f360435749f85e4e88579f632e105af5324b8c8b3216377ece000
dprint-x86_64-unknown-linux-musl.zip b1365945a2c7ab51fa3c62221b3f984ba9971357e122dbf3817bdf02936f548a
dprint-aarch64-unknown-linux-gnu.zip e8ca4911be033b60f5531e0d51a5d1f126b8c68e193f85024627dac58e63294d
dprint-aarch64-unknown-linux-musl.zip 12864a0ebe6274f9f4b647e6ae2abc5eb33ace9e722d94bd23942a2975783e18
dprint-riscv64gc-unknown-linux-gnu.zip 825ce485ea3a9a61f691de1c85542a278e22c8c08d4dca9fb8e4224ab4319c59
dprint-loongarch64-unknown-linux-gnu.zip 93876d849b3d60bb2d1a53d6929f59143fddf92bcebd3510c255ae2a51c13863
dprint-loongarch64-unknown-linux-musl.zip 6fb899b90097f70f38f5aa932cb54e38be14caf059dde0fd92ab25c99232631c
dprint-powerpc64le-unknown-linux-gnu.zip 7d31dca732bb9b56e15d491df80c5ab6088378e67a4191de29152cbee3058496
dprint-powerpc64le-unknown-linux-musl.zip f41fded113c462e1d3223da3d2038e34719f1be333d5afd6c906b2b4285a0388
dprint-aarch64-linux-android.zip e97871899873f41aef9e7f2a6089cec229dd66505b8373ef294db6b8a82563dc
dprint-x86_64-linux-android.zip 87b9d3e407c5341e4d8471fd00260e254615d46bc1a27f482b3989052a89b6c6

Don't miss a new dprint release

NewReleases is sending notifications on new releases.