package.json — shell commands the package manager runs at specific points during installation or removal.
Common lifecycle scripts:
| Script | When it runs |
|---|---|
preinstall | Before the package is installed |
install | During installation |
postinstall | After the package is installed |
preuninstall | Before the package is uninstalled |
prepublishOnly | Before the package is published |
prepare | After install and before publish |
Bun’s security model
Unlike npm, yarn, and pnpm, Bun does not run lifecycle scripts for installed dependencies by default. Arbitrary scripts executed silently during installation represent a supply chain attack vector. Instead, Bun uses a “default-secure” approach: scripts only run for packages you have explicitly trusted.Your own project’s scripts
Lifecycle scripts defined in your ownpackage.json (the root package) always run. Only scripts belonging to installed dependencies are blocked by default.
Trusting a dependency’s lifecycle scripts
Add the package name totrustedDependencies in your root package.json, then reinstall:
postinstall (and other lifecycle scripts) for node-sass and esbuild.
Default trusted packages
The top 500 npm packages that commonly require lifecycle scripts (such asesbuild, sharp, node-sass, @swc/core) are trusted automatically. You can view the full list on GitHub.
The default trusted list applies only to packages installed from npm. Packages from
file:, link:, git:, or github: sources must be explicitly added to trustedDependencies, even if the package name appears on the default list.Viewing blocked scripts
To see which installed packages had their lifecycle scripts blocked:Trusting packages interactively
To run blocked scripts and add the package totrustedDependencies in one step:
Disabling all lifecycle scripts
To skip lifecycle scripts for every package, including trusted ones:Concurrent scripts
Lifecycle scripts run in parallel during installation. The default concurrency is two times the reported CPU count (orGOMAXPROCS). To adjust:
bunfig.toml: