This page documents the code formatting setup for the TypeScript repository using dprint. It covers the configuration file, which file types are formatted, the rules enforced, and how to run formatting checks locally and in CI.
For information about the broader editor and workspace configuration, see Editor and Formatting Configuration. For the git hook that enforces formatting on commit, see Git Configuration.
The TypeScript repository uses dprint as its single code formatter for TypeScript, JavaScript, JSON, and YAML files. Formatting is enforced automatically in CI via a dedicated check-format task, and optionally on save in VS Code. The canonical configuration lives in .dprint.jsonc
dprint is installed as a dev dependency and is invoked through the hereby build system. Contributors should not need to install dprint globally.
Three dprint-related packages appear in devDependencies (package.json42-44):
| Package | Version | Role |
|---|---|---|
dprint | ^0.49.1 | CLI binary used to run fmt and check commands |
@dprint/formatter | ^0.4.1 | Node.js programmatic API (WASM-based) |
@dprint/typescript | 0.93.4 (pinned) | TypeScript plugin used by dtsBundler.mjs |
The TypeScript plugin version is pinned (not a range) because it must match the .wasm plugin URL specified in .dprint.jsonc. A comment in .dprint.jsonc54 notes: "if updating typescript, update the one in package.json".
The entire dprint configuration resides in .dprint.jsonc
| Key | Value | Meaning |
|---|---|---|
indentWidth | 4 | Four spaces for indentation |
lineWidth | 1000 | Effectively disables line-length wrapping |
newLineKind | "auto" | Inherits newline style from the file (overridden per language) |
useTabs | false | Spaces, not tabs |
These rules apply to all .ts, .tsx, .js, and .jsx files:
| Option | Value | Notes |
|---|---|---|
newLineKind | "crlf" | Overrides global — CRLF line endings in TypeScript files |
semiColons | "always" | Semicolons required |
quoteStyle | "preferDouble" | Double quotes for strings |
quoteProps | "consistent" | All props quoted or none |
useBraces | "whenNotSingleLine" | Omit braces on single-line bodies |
bracePosition | "sameLineUnlessHanging" | Opening brace on same line unless hanging |
singleBodyPosition | "sameLine" | Single-statement bodies stay on same line |
nextControlFlowPosition | "nextLine" | else/catch/finally on a new line (Stroustrup style) |
trailingCommas | "onlyMultiLine" | Trailing commas on multi-line lists only |
preferHanging | false | |
operatorPosition | "maintain" | Preserve existing operator positions |
arrowFunction.useParentheses | "preferNone" | Omit parens on single-parameter arrow functions |
conditionalExpression.linePerExpression | false | Keep ternary "match/case" style |
functionExpression.spaceAfterFunctionKeyword | true | Space between function and ( |
importDeclaration.forceMultiLine | "whenMultiple" | Multi-line import when two or more named imports |
module.sortImportDeclarations | "caseInsensitive" | Imports auto-sorted |
module.sortExportDeclarations | "caseInsensitive" | Exports auto-sorted |
exportDeclaration.sortNamedExports | "caseInsensitive" | Named exports sorted |
importDeclaration.sortNamedImports | "caseInsensitive" | Named imports sorted |
| Option | Value |
|---|---|
indentWidth | 2 (overrides global 4) |
quotes | "preferSingle" |
| Option | Value | Notes |
|---|---|---|
trailingCommas | "never" | Trailing commas disabled — VS Code warns on JSONC trailing commas |
dprint skips the following:
**/.git
**/node_modules
**/*-lock.json (e.g. package-lock.json)
coverage/**
lib/** (LKG library files)
built/** (build output)
tests/** (test case files)
internal/**
**/*.generated.* (generated files like diagnosticInformationMap.generated.ts)
scripts/*.d.*
**/_namespaces/** (barrel namespace files)
Plugins are loaded from WASM URLs. The versions are pinned to exact patch versions:
| Plugin | Purpose |
|---|---|
typescript-0.93.4.wasm | TypeScript and JavaScript |
json-0.19.4.wasm | JSON and JSONC |
g-plane/pretty_yaml-v0.5.0.wasm | YAML |
| Command | What it does |
|---|---|
dprint fmt | Format all files in place |
dprint check | Check formatting, exit non-zero if any file differs |
npm run format | Alias for dprint fmt (package.json100) |
Two tasks in Herebyfile.mjs wrap the dprint CLI:
format task — rewrites files in place:
hereby format
Internally: node node_modules/dprint/bin.js fmt
check-format task — exits non-zero if any file is not formatted:
hereby check-format
Internally: node node_modules/dprint/bin.js check
The following diagram shows every place in the repository that invokes dprint or depends on its configuration.
dprint invocation and configuration flow
Sources: .dprint.jsonc Herebyfile.mjs588-598 scripts/dtsBundler.mjs8-9 .vscode/settings.template.json10-13 .vscode/extensions.json4
Which file types dprint formats and which it excludes
Sources: .dprint.jsonc40-52
.vscode/settings.template.json9-13 configures VS Code to use the dprint.dprint extension as the default formatter for all dprint-supported languages:
.ts, .tsx).js, .jsx)The setting "editor.formatOnSave": true is included, so saving a file automatically formats it. The extension is also listed as a recommended extension in .vscode/extensions.json4 and is pre-installed in the dev container (.devcontainer/devcontainer.json36-38).
The settings.template.json file also aligns VS Code's organize-imports collation with dprint's import sort order (.vscode/settings.template.json25-38):
organizeImportsCollation: "unicode"
organizeImportsCaseFirst: "upper"
organizeImportsIgnoreCase: false
organizeImportsNumericCollation: true
scripts/dtsBundler.mjs uses the Node.js dprint API directly to format the generated typescript.d.ts bundle (scripts/dtsBundler.mjs8-9):
import * as dprintFormatter from "@dprint/formatter";
import * as dprintTypeScript from "@dprint/typescript";
This means the bundler applies the same TypeScript formatting rules to the emitted declaration file without invoking the CLI. The comment in .dprint.jsonc1 notes: "If updating this, also update the config in dtsBundler.mjs" — the bundler embeds a subset of the dprint config inline.
The check-format hereby task is run as part of the main CI pipeline. It uses the --ignoreStdout flag so only failures (non-zero exit) are surfaced (Herebyfile.mjs594-598). A formatting violation fails the CI job, requiring contributors to run hereby format (or npm run format) locally before pushing.
The npm run format shortcut (package.json100) is equivalent to running dprint fmt directly.
When updating the dprint TypeScript plugin, two places must be kept in sync:
@dprint/typescript package version in package.json (package.json43).wasm URL version in .dprint.jsonc (.dprint.jsonc56)The comment at .dprint.jsonc53-54 reminds contributors: "if adding new languages, make sure settings.template.json is updated too" — the VS Code language selector in settings.template.json must include any newly formatted file types.
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.