aws / aws/aws-cdk

(aws-lambda-nodejs): `devEngines` field not propagated during nodeModules bundling

Open
#37,942 2 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-lambda-nodejs bug effort/small p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
1d 19h
Merged PRs (30d)
74

Description

### Describe the bug

When using `aws-lambda-nodejs` with the `nodeModules` option, there is currently no way to control which version of the package manager is used to install dependencies during bundling. The bundler generates a minimal `package.json` in the output directory, but does not forward any package manager constraints from the project's `package.json`.

Two common ways to declare a package manager version in `package.json` are the `packageManager` field and the `devEngines` field:

```json
{
"packageManager": "npm@10.8.0"
}
```

```json
{
"devEngines": {
"packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
}
}
```

The `devEngines` field is a standard [defined by the OpenJS Foundation](https://github.com/openjs-foundation/package-metadata-interoperability-working-group/blob/main/devengines-field-proposal.md) that allows projects to declare package manager and runtime requirements for development. Package managers such as npm (>= 10.4 with Corepack) and pnpm use this field to enforce or warn when the wrong package manager or version is used. Because neither field is forwarded into the generated `package.json`, these constraints are silently ignored during the `nodeModules` install step, making it impossible to enforce package manager version consistency during Lambda bundling.

### Regression Issue

- [ ] Select this option if this issue appears to be a regression.

### Last Known Working CDK Library Version

_No response_

### Expected Behavior

When a `devEngines` field is present in the project's `package.json`, it should be forwarded into the minimal `package.json` that `aws-lambda-nodejs` writes to the asset output directory during `nodeModules` bundling. Allowing package managers that support `devEngines` to enforce the declared package manager and version during the install step.

### Current Behavior

The generated `package.json` only contains the `dependencies` field. The `devEngines` field is always omitted, even when it is present in the nearest parent `package.json`. As a result, tools like npm with Corepack cannot enforce the declared package manager during bundling.

For example, given a `package.json` like:

```json
{
"devEngines": {
"packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
},
"dependencies": {
"delay": "5.0.0"
}
}
```

The generated `package.json` in the asset output directory will be:

```json
{ "dependencies": { "delay": "5.0.0" } }
```

The `devEngines` constraint is silently dropped.

### Reproduction Steps

```ts
import * as path from 'path';
import * as cdk from 'aws-cdk-lib';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';

// package.json in the project root contains:
// {
// "devEngines": {
// "packageManager": { "name": "npm", "version": ">=10", "onFail": "error" }
// },
// "dependencies": { "delay": "5.0.0" }
// }

const app = new cdk.App();
const stack = new cdk.Stack(app, 'TestStack');

new NodejsFunction(stack, 'MyFunction', {
entry: path.join(__dirname, 'handler.ts'),
runtime: Runtime.NODEJS_20_X,
bundling: {
nodeModules: ['delay'],
},
});

app.synth();

// Inspect the generated package.json in cdk.out//package.json
// Expected: { "devEngines": { "packageManager": { ... } }, "dependencies": { "delay": "5.0.0" } }
// Actual: { "dependencies": { "delay": "5.0.0" } }
```

### Possible Solution

At bundling time, read the `devEngines` field from the nearest `package.json` by walking up the directory tree from the entry file. If the field is present, include it in the generated `package.json` written to the output directory.

### Additional Information/Context

This issue was discovered due to the situation described in https://github.com/aws/aws-cdk/issues/37898 but we haven't migrated to pnpm v11 yet and our version specification is not being respected.

https://github.com/openjs-foundation/package-metadata-interoperability-working-group/blob/main/devengines-field-proposal.md
https://github.com/pnpm/pnpm/issues/8153

### AWS CDK Library version (aws-cdk-lib)

2.252.0

### AWS CDK CLI version

2.1120.0

### Node.js Version

24.x

### OS

macOS

### Language

TypeScript

### Language Version

5.x

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the aws-lambda-nodejs nodeModules bundling path that writes the minimal package.json in the asset output directory, using the entry file handler.ts and its nearest parent package.json as the inputs. Confirm the generated package.json preserves devEngines alongside dependencies, then verify the bundling behavior described in the reproduction steps.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, node.js, typescript
Domain
build-system, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.