# Risk map — prettier/prettier

> Canonical page: https://codevetter.com/unpack/prettier/risk-map

# Risk map — prettier/prettier

Scanned commit 1a36a7defdcccfc4967e99bbf9517a02ab2345b2 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The largest security surface is intentional code execution: config files and plugins are imported from user-controlled paths, and --write overwrites arbitrary matched files. Plugin last-wins lets a later plugin replace builtin parsers/printers. Cache writes with restrictAccessToCwd:false. Generated plugin registries and the dist/ publish boundary are easy to edit in the wrong place. Option policy and the removed custom-parser API are social/API traps, not memory-safety bugs.
- loadPlugin/importPlugin will import() a URL, an absolute path, a cwd-relative file, or a node_modules specifier via importFromDirectory (import-meta-resolve from a fake noop.js parent). This is how --plugin and config plugins run third-party code in-process. — [src/main/plugins/load-plugin.js#L11-55](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/main/plugins/load-plugin.js#L11-L55) [src/utilities/import-from-directory.js#L1-8](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/utilities/import-from-directory.js#L1-L8) [src/utilities/import-from-file.js#L1-8](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/utilities/import-from-file.js#L1-L8)
- JS/TS Prettier configs are executed, not parsed: loaders['.js'|'.mjs'|'.cjs'|'.ts'|'.mts'|'.cts'] = importModuleDefault via import(pathToFileURL(file)). External string configs try requireFromFile first then importFromFile. — [src/config/prettier-config/loaders.js#L19-109](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/config/prettier-config/loaders.js#L19-L109) [src/config/prettier-config/load-external-config.js#L10-33](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/config/prettier-config/load-external-config.js#L10-L33)
- --write calls mockable.writeFormattedFile(filename, output) which is fs.writeFile; expandPatterns can match any non-ignored file under cwd. docs/cli.md warns this overwrites files. process.exitCode is set per-file rather than aborting the whole run on a single IO error. — [src/cli/mockable.js#L8-14](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/mockable.js#L8-L14) [src/cli/format.js#L412-433](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/format.js#L412-L433) [docs/cli.md#L18-28](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/docs/cli.md#L18-L28)
- FormatResultsCache constructs file-entry-cache with restrictAccessToCwd: false. --cache-location can point anywhere that is not a directory; default falls back to os.tmpdir() if find-cache-directory fails. — [src/cli/format-results-cache.js#L42-51](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/format-results-cache.js#L42-L51) [src/cli/find-cache-file.js#L10-34](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/find-cache-file.js#L10-L34)
- Parser/printer lookup uses plugins.findLast, so a user or config plugin can silently replace babel/estree/html printers. Integration tests exist for plugin-override-builtin-printers and plugin-override-buitin-plugins (filename typo). — [src/main/parser-and-printer.js#L18-47](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/main/parser-and-printer.js#L18-L47) [tests/integration/__tests__/plugin-override-builtin-printers.js](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/tests/integration/__tests__/plugin-override-builtin-printers.js) [tests/integration/__tests__/plugin-override-buitin-plugins.js](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/tests/integration/__tests__/plugin-override-buitin-plugins.js)
- scripts/release/release.js uses child_process.exec(command) for git fetch --tags and yarn before importing run.js. The comment says it cannot use dependencies because they may not be installed yet. This is maintainer-only, not the formatter runtime. — [scripts/release/release.js#L1-30](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/scripts/release/release.js#L1-L30)
- development-plugins.js and production-plugins.js are generated ('do NOT edit'); editing them by hand will be overwritten by yarn generate-builtin-plugins. Production plugin graph (src/plugins/*.js) is a different split than language-* modules. — [src/main/plugins/builtin-plugins/development-plugins.js#L1-4](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/main/plugins/builtin-plugins/development-plugins.js#L1-L4) [src/main/plugins/builtin-plugins/production-plugins.js#L1-4](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/main/plugins/builtin-plugins/production-plugins.js#L1-L4) [scripts/generate-builtin-plugins.js#L13-31](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/scripts/generate-builtin-plugins.js#L13-L31) [src/plugins/babel.js#L1-5](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/plugins/babel.js#L1-L5)
- src/index.cjs in non-production throws if prettier.util or prettier.doc is accessed (ESM-only in dev CJS). Production CJS requires those files directly. Mixing NODE_ENV and CJS consumers is a support trap. — [src/index.cjs#L41-75](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/index.cjs#L41-L75)
- Custom Parser API was removed in v3.0.0 (docs/api.md); plugins must use the Plugin API. printer.embed with >2 parameters throws, telling authors the v3 plugin API changed. — [docs/api.md#L141-149](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/docs/api.md#L141-L149) [src/main/multiparser.js#L25-28](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/main/multiparser.js#L25-L28)
- No-new-options policy is enforced socially: CONTRIBUTING.md and docs/option-philosophy.md say option-request PRs are closed without discussion. Agents that add a formatting flag will be rejected. — [CONTRIBUTING.md#L87-89](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/CONTRIBUTING.md#L87-L89) [docs/option-philosophy.md#L8-42](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/docs/option-philosophy.md#L8-L42)
- handleError maps UndefinedParserError to exit 2 (or ignore with --ignore-unknown); ConfigError/validation calls process.exit(1) immediately (fails the whole CLI); parse errors set exitCode 2 and continue. Check mode uses exit 1 for unformatted files. — [src/cli/format.js#L26-72](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/format.js#L26-L72) [src/cli/format.js#L496-504](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/src/cli/format.js#L496-L504) [docs/cli.md#L94-102](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/docs/cli.md#L94-L102)
- Website playground Worker loads /worker.mjs?version= and production Vite aliases npm deps to esm.sh CDN URLs (website/vite.config.mjs buildCdnAlias). That is a supply-chain/runtime dependency of prettier.io, not of the formatter library. (inferred) — [website/playground/composables/prettier-worker.js#L10-17](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/website/playground/composables/prettier-worker.js#L10-L17) [website/vite.config.mjs#L53-79](https://github.com/prettier/prettier/blob/1a36a7defdcccfc4967e99bbf9517a02ab2345b2/website/vite.config.mjs#L53-L79)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
