package.json
Il file manifesto di un pacchetto. Contiene tutti i metadati del pacchetto, comprese le dipendenze, il titolo, l'autore, eccetera. This is a standard preserved across all major Node.js package managers, including pnpm.
In addition to the traditional package.json
format, pnpm also supports package.json5
(via json5) and package.yaml
(via js-yaml).
engines
Puoi specificare la versione di Node e pnpm su cui funziona il tuo software:
{
"engines": {
"node": ">=10",
"pnpm": ">=3"
}
}
Durante lo sviluppo locale, pnpm fallirà sempre con un messaggio di errore se la sua versione non corrisponde a quella specificata nel campo engine
.
Unless the user has set the engineStrict
config flag (see settings), this field is advisory only and will only produce warnings when your package is installed as a dependency.
devEngines.runtime
Added in: v10.14
Allows to specify one or more JavaScript runtime engines used by the project. Supported runtimes are Node.js, Deno, and Bun.
For instance, here is how to add node@^24.4.0
to your dependencies:
{
"devEngines": {
"runtime": {
"name": "node",
"version": "^24.4.0",
"onFail": "download"
}
}
}
You can also add multiple runtimes to the same package.json
:
{
"devEngines": {
"runtime": [
{
"name": "node",
"version": "^24.4.0",
"onFail": "download"
},
{
"name": "deno",
"version": "^2.4.3",
"onFail": "download"
}
]
}
}
How it works:
pnpm install
resolves your specified range to the latest matching runtime version.- The exact version (and checksum) is saved in the lockfile.
- Scripts use the local runtime, ensuring consistency across environments.
dependenciesMeta
Ulteriori informazioni meta utilizzate per le dipendenze dichiarate all'interno di dependencies
, optionalDependencies
e devDependencies
.
dependenciesMeta.*.injected
If this is set to true
for a dependency that is a local workspace package, that package will be installed by creating a hard linked copy in the virtual store (node_modules/.pnpm
).
If this is set to false
or not set, then the dependency will instead be installed by creating a node_modules
symlink that points to the package's source directory in the workspace. This is the default, as it is faster and ensures that any modifications to the dependency will be immediately visible to its consumers.
For example, suppose the following package.json
is a local workspace package:
{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0"
}
}
The button
dependency will normally be installed by creating a symlink in the node_modules
directory of card
, pointing to the development directory for button
.
But what if button
specifies react
in its peerDependencies
? If all projects in the monorepo use the same version of react
, then there is no problem. But what if button
is required by card
that uses react@16
and form
that uses react@17
? Normally you'd have to choose a single version of react
and specify it using devDependencies
of button
. Symlinking does not provide a way for the react
peer dependency to be satisfied differently by different consumers such as card
and form
.
The injected
field solves this problem by installing a hard linked copies of button
in the virtual store. To accomplish this, the package.json
of card
could be configured as follows:
{
"name": "card",
"dependencies": {
"button": "workspace:1.0.0",
"react": "16"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}
Whereas the package.json
of form
could be configured as follows:
{
"name": "form",
"dependencies": {
"button": "workspace:1.0.0",
"react": "17"
},
"dependenciesMeta": {
"button": {
"injected": true
}
}
}
With these changes, we say that button
is an "injected dependency" of card
and form
. When button
imports react
, it will resolve to react@16
in the context of card
, but resolve to react@17
in the context of form
.
Because injected dependencies produce copies of their workspace source directory, these copies must be updated somehow whenever the code is modified; otherwise, the new state will not be reflected for consumers. When building multiple projects with a command such as pnpm --recursive run build
, this update must occur after each injected package is rebuilt but before its consumers are rebuilt. For simple use cases, it can be accomplished by invoking pnpm install
again, perhaps using a package.json
lifecycle script such as "prepare": "pnpm run build"
to rebuild that one project. Third party tools such as pnpm-sync and pnpm-sync-dependencies-meta-injected provide a more robust and efficient solution for updating injected dependencies, as well as watch mode support.