Summary
Togoder Security scanned the npm package prettier@3.9.9 on Oct 6, 2026. An AI review of 9 source files produced 1 medium, 6 low severity findings. The overall verdict is medium: the findings flag risky but common patterns (dynamic code, unsafe defaults, broad file or network access) rather than confirmed malware.
Findings 7
Dynamic module loading with computed input
NPS-D4F4C8FA571B
The getModule function performs a dynamic import using a path derived from runtime input (modulePath). The path is ultimately constructed from the plugin name supplied in formatOptions.plugins. Although getPluginPath attempts to resolve the plugin under the current working directory's index.js, the fallback getModulePath(name, rootPath) invokes Node's module resolution, which can resolve bare specifiers and potentially load arbitrary modules. If plugins or their names are attacker-controlled (e.g., via configuration or input), this can lead to loading and executing untrusted code.
Dynamic code execution
NPS-28C7E3257498
Uses new Function('module', 'return import(module)') to perform dynamic import. While this is a known pattern in Prettier's CLI launcher to load ESM from CJS, use of new Function constitutes dynamic code execution and could be abused if the module path were attacker-controlled.
Dynamic imports with computed/external input
NPS-114EA379F10F
Dynamically imports ../internal/experimental-cli.mjs or ../internal/legacy-cli.mjs based on environment variable PRETTIER_EXPERIMENTAL_CLI and command-line flag. Module paths are hardcoded relative paths, so risk is limited, but behavior is influenced by env/CLI input.
Process signal handling and termination
NPS-2439F9063387
The when-exit Interceptor registers handlers for numerous signals (SIGHUP, SIGINT, SIGTERM, SIGALRM, SIGABRT, etc.) and can call process.kill(process.pid, signal) to re-raise signals. This alters default process termination behavior and could interfere with expected signal semantics in a parent process.
Top-level side effect: process exit interceptor registration
NPS-779757DFA076
The when-exit module (node_default(Temp.purgeSyncAll)) registers signal handlers and an exit hook at import time. This runs code on import without user interaction, manipulating process exit behavior. While common for cleanup utilities, it is a top-level side effect that modifies global process state.
File system manipulation outside package scope
NPS-EFCD6A2C7338
The ionstore NodeStore writes to a predictable temporary file in os.tmpdir() (ionstore_<id>.json). The id is validated by a regex in the AbstractStore constructor, limiting the risk, but the library still reads/writes files outside its package directory, which could potentially be abused if ids or data are influenced by external input.
Dynamic module loading (benign)
NPS-9B7A98921B4D
The code uses process.getBuiltinModule('node:diagnostics_channel') wrapped in try/catch to optionally load a Node.js built-in module for tracing. This is a legitimate feature for telemetry hooks, not external code loading.
Files reviewed
| File | Verdict | What the reviewer saw |
|---|---|---|
| bin/prettier.cjs | medium | The file is a legitimate Prettier CLI launcher that uses a dynamic import wrapper and environment/CLI-controlled branching, but contains no data exfiltration, credential harvesting, obfuscation, or malicious behavior. |
| internal/experimental-cli-worker.mjs | medium | No obvious malicious exfiltration or credential harvesting was found, but the code contains dynamic module loading from computed paths and global process/FS side effects that warrant caution. |
| doc.js | safe | No malicious patterns detected; the file is a UMD bundle of Prettier's document printer with no network, filesystem, process, or dynamic code execution behaviors. |
| doc.mjs | safe | No malicious patterns detected; the file contains standard Prettier-style document printing utilities with no network, filesystem, process, or dynamic code execution behavior. |
| index.cjs | safe | This is a bundled build of the Prettier library (version 3.9.9) containing only legitimate formatting utilities, text-processing shims, and standard ESM-to-CJS interop helpers with no malicious patterns. |
| plugins/graphql.js | safe | No malicious patterns detected; this is a legitimate Prettier GraphQL plugin with only benign Node.js diagnostics_channel usage for optional tracing. |
| plugins/graphql.mjs | safe | This is the Prettier GraphQL plugin; it contains only parser/printer logic with no malicious patterns, network activity, credential access, process spawning, or obfuscation. |
| standalone.js | safe | This is the standard Prettier standalone bundle (v3.9.9); no malicious patterns, exfiltration, obfuscation, or suspicious behavior detected. |
| standalone.mjs | safe | No malicious patterns detected; the file is a minified bundle of the Prettier code formatter with no exfiltration, credential harvesting, dynamic code execution, or network/process activity. |
Scanned versions of prettier
| Version | Verdict | Files | Scanned |
|---|---|---|---|
| 3.9.9 | Needs review | 9 | Oct 6, 2026 |
Frequently asked questions
Is prettier safe to use?
No confirmed malware was found in prettier@3.9.9, but the review flagged 1 medium, 6 low severity findings for risky patterns worth checking before you rely on it.
Does prettier contain malware?
No malware was identified in prettier@3.9.9 when Togoder Security scanned it on Oct 6, 2026. A new version can still introduce malicious code, so scan the exact versions in your lockfile.
How was prettier checked?
Togoder Security downloaded the published npm package and had an AI model read its 9 source files, looking for install scripts, credential access, network exfiltration, obfuscation, backdoors and crypto-wallet theft. The results are cached by file hash and shown here.
How do I scan prettier together with the rest of my dependencies?
Upload your lockfile at https://security.togoder.click/scan or call the API documented at https://security.togoder.click/api-docs. Files that have already been scanned, like the ones in prettier@3.9.9, cost nothing.