Skip to content

feat: let .corepack.env be a lock file#668

Open
aduh95 wants to merge 2 commits into
nodejs:mainfrom
aduh95:corepack.env-lockfile
Open

feat: let .corepack.env be a lock file#668
aduh95 wants to merge 2 commits into
nodejs:mainfrom
aduh95:corepack.env-lockfile

Conversation

@aduh95

@aduh95 aduh95 commented Feb 28, 2025

Copy link
Copy Markdown
Contributor

With #642 and #643 landed, we can consider using .corepack.env as a lockfile. If the package.json defines a devEngines.packageManager, we can accept an env variable that defines the exact version Corepack should be using; if that version is put in a .corepack.env (Node.js 20+ users only), it's effectively a lockfile.

I'm not a fan of the env variable name chosen, happy to use a different one.

Fixes: #402
Fixes: #95
Fixes: #682

@styfle

styfle commented Mar 1, 2025

Copy link
Copy Markdown
Member

To be clear, this is only going to update .corepack.env if it already exists.

Its not going to create .corepack.env if it does not exist, right?

@aduh95

aduh95 commented Mar 1, 2025

Copy link
Copy Markdown
Contributor Author

To be clear, this is only going to update .corepack.env if it already exists.

Its not going to create .corepack.env if it does not exist, right?

Yes correct, if it exists and contains the env key – so it’s currently opt-in, I think we could discuss whether we want to flip that to opt-out once the parseEnv thing is no longer experimental.

@arcanis arcanis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need that considering that packageManager can already be used as a lock for devEngines.packageManager?

@aduh95

aduh95 commented Mar 1, 2025

Copy link
Copy Markdown
Contributor Author

Why do we need that considering that packageManager can already be used as a lock for devEngines.packageManager?

So one can git ignore it I believe is the ask

@arcanis

arcanis commented Mar 1, 2025

Copy link
Copy Markdown
Contributor

I'm not sure I follow the use case. Why would they use Corepack (or devEngine) if they don't want to lock the version in the project?

@zanminkian

zanminkian commented Mar 21, 2025

Copy link
Copy Markdown
Contributor

@arcanis I have the same use-case as @aduh95. When developing some old projects, they usually reject to add packageManager and devEngines field to package.json. Corepack is convenient for me but not every team member like it. I can use corepack with a git ignored .corepack.env file on my own way.

@arcanis

arcanis commented Mar 21, 2025

Copy link
Copy Markdown
Contributor

Then disable auto pinning? I don't think this behavior should have been made the default anyway.

@aduh95

aduh95 commented Mar 21, 2025

Copy link
Copy Markdown
Contributor Author

@zanminkian could you give an example of use case where putting a .gitignored .corepack.env with COREPACK_ENABLE_AUTO_PIN=0 would not fulfill your needs?

@styfle

styfle commented Mar 21, 2025

Copy link
Copy Markdown
Member

Then disable auto pinning? I don't think this behavior should have been made the default anyway.

I tend to agree. I believe the default auto-pinning was added as a response to earlier TSC meetings where this was a recommendation to making corepack stable and default enabled with node distributions.

Now that corepack is no longer going to be bundled with node, we could consider disabling the auto pinning behavior.

@kindera9699-spec

Copy link
Copy Markdown

With #642 and #643 landed, we can consider using .corepack.env as a lockfile. If the package.json defines a devEngines.packageManager, we can accept an env variable that defines the exact version Corepack should be using; if that version is put in a .corepack.env (Node.js 20+ users only), it's effectively a lockfile.

I'm not a fan of the env variable name chosen, happy to use a different one.

Fixes: #402 Fixes: #95 Fixes: #682

Closed

@escalonn

Copy link
Copy Markdown

docker wants corepack to be able to discover packageManager outside package.json, because otherwise, you have to either

  1. copy package.json before anything else, so if you are incrementing your version there on every deploy, you can't do any layer caching, or
  2. have nice caching, but you have to let corepack pick a random version of your package manager for the lock-file-based install, then get the correct version for subsequent commands after the package.json is copied in

@khokm

khokm commented Apr 27, 2026

Copy link
Copy Markdown

docker wants corepack to be able to discover packageManager outside package.json, because otherwise, you have to either

  1. copy package.json before anything else, so if you are incrementing your version there on every deploy, you can't do any layer caching, or
  2. have nice caching, but you have to let corepack pick a random version of your package manager for the lock-file-based install, then get the correct version for subsequent commands after the package.json is copied in

This can probably be solved by using multiple stages:

FROM node:20-alpine AS corepack-extract

WORKDIR /app

# jq is required to filter JSON content
RUN apk add --no-cache jq

# Copy full package.json only in this stage
COPY package.json .

# Create a minimal package.json containing only packageManager
# Key point: Corepack reads only this file, so it is isolated
# from all other changes in package.json
RUN jq '{packageManager}' package.json > package.corepack.json

FROM node:20-alpine AS deps

WORKDIR /app

# Use minimal package.json so Corepack sees only packageManager
# and does not react to unrelated changes in dependencies or metadata
COPY --from=corepack-extract /app/package.corepack.json ./package.json

# Enable Corepack (disabled by default in some Node images)
RUN corepack enable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

7 participants