Automatically detects and runs npm/yarn/pnpm install in non-interactive mode after container creation.
- Automatic detection: Detects package manager based on lockfile (pnpm-lock.yaml, yarn.lock, package-lock.json)
- Corepack support: Automatically installs and enables corepack if
packageManagerfield is found in package.json (required for Node 24+) - Non-interactive mode: Sets
CI=trueto avoid prompts (e.g., pnpm won't ask to delete node_modules) - Smart command selection: Uses
npm ci,pnpm install --frozen-lockfile, oryarn install --immutablewhen lockfiles exist - Flexible configuration: Override package manager, command, and working directory
- Skip if exists: Optionally skip installation if node_modules already exists
- Multi-root support: Auto-discover VS Code/Cursor
.code-workspaceand IntelliJ.idea/modules.xmlproject files to install across all workspace folders
Add this feature to your devcontainer.json:
{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {}
}
}This will:
- Detect the package manager from lockfile
- Run the appropriate install command automatically
- Set
CI=trueto prevent interactive prompts
If you have this in your devcontainer.json, you can now remove it:
{
"postCreateCommand": "CI=true pnpm install" // ❌ Not needed anymore
}| Option | Type | Default | Description |
|---|---|---|---|
command |
string | auto |
Installation command: install, ci, or auto to detect |
packageManager |
string | auto |
Package manager: npm, yarn, pnpm, or auto to detect |
workingDirectory |
string | /workspaces/${localWorkspaceFolderBasename} |
Directory where to run install. Overridden by directories. Used as fallback scan root when autoDiscover finds no workspace files. |
skipIfNodeModulesExists |
boolean | false |
Skip if node_modules exists |
additionalArgs |
string | "" |
Additional arguments for install command |
directories |
string | "" |
Comma-separated list of directories to install in. Overrides workingDirectory and autoDiscover. |
autoDiscover |
boolean | false |
Scan /workspaces for VS Code/Cursor .code-workspace and IntelliJ .idea/modules.xml files and install in every discovered folder with a package.json. |
{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"packageManager": "pnpm"
}
}
}{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"packageManager": "npm",
"command": "ci"
}
}
}{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"skipIfNodeModulesExists": true
}
}
}{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"additionalArgs": "--ignore-scripts"
}
}
}{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"workingDirectory": "/workspace/frontend"
}
}
}When your devcontainer uses a .code-workspace file with multiple folders, enable autoDiscover to install packages in every discovered folder:
{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"autoDiscover": true
}
}
}The feature scans /workspaces (depth 3) for *.code-workspace files, parses the folders[].path array, resolves relative paths, and runs the appropriate package manager in each folder that contains a package.json. Each folder may use a different package manager — detection runs independently per folder.
autoDiscover: true also scans for .idea/modules.xml files (depth 4) and extracts module root directories from the filepath attributes.
For any IDE that does not have a parseable workspace file (Zed, Neovim, etc.) or when you want precise control:
{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"directories": "/workspaces/frontend,/workspaces/backend,/workspaces/shared"
}
}
}directories takes precedence over both workingDirectory and autoDiscover.
Corepack Support (Node 24+)
If your package.json contains a packageManager field (e.g., "packageManager": "pnpm@9.0.0"):
- The feature checks if corepack is available
- If not, it installs corepack globally with
npm install -g corepack - Enables corepack with
corepack enable - Corepack then automatically installs and uses the exact package manager version specified
This is particularly important for Node 24+ where corepack is no longer included by default.
The feature detects the package manager in this order:
- From
packageManagerfield in package.json (highest priority)- Example:
"packageManager": "pnpm@9.0.0"→ uses pnpm - This is the most reliable and modern approach
- Example:
- From lockfiles:
pnpm-lock.yaml→ uses pnpmyarn.lock→ uses yarnpackage-lock.json→ uses npm
- Default: Falls back to npm if nothing is detected
For each package manager:
- npm: Uses
npm ciif package-lock.json exists, otherwisenpm install - pnpm: Uses
pnpm install --frozen-lockfileif pnpm-lock.yaml exists, otherwisepnpm install - yarn:
- Yarn 2+: Uses
yarn install --immutableif yarn.lock exists - Yarn 1.x: Uses
yarn install --frozen-lockfileif yarn.lock exists
- Yarn 2+: Uses
The feature sets CI=true environment variable, which:
- pnpm: Automatically removes old node_modules without prompting
- npm: Enables strict mode in
npm ci - yarn: Enables immutable installs
The feature uses installsAfter to ensure it runs after:
ghcr.io/devcontainers/features/common-utilsghcr.io/devcontainers/features/node
The actual package installation runs in postCreateCommand, which is the last lifecycle hook after all features are installed.
Check that:
package.jsonexists in the working directory- The package manager is installed (use node feature or appropriate base image)
Force the package manager explicitly:
{
"features": {
"ghcr.io/helpers4/devcontainer/package-auto-install:1": {
"packageManager": "pnpm"
}
}
}Check the container logs during creation. The feature will show the exact command being run and any errors.
You can manually run the installation script:
/usr/local/bin/devcontainer-package-install- v1.0.2: Added
autoDiscover(scan VS Code/Cursor.code-workspaceand IntelliJ.idea/modules.xml) anddirectories(explicit comma-separated list) options for multi-root workspace support. Each folder runs package manager detection independently. - v1.0.1: Added corepack support for Node 24+ (
packageManagerfield in package.json). - v1.0.0: Initial release.
LGPL-3.0 - See LICENSE file for details