This is the canonical statement; [dev-environment.md](dev-environment.md#nodejs) and [cdk-project-layout.md](cdk-project-layout.md#lambda-defaults) defer to it.
- **`nodejs24.x` is the standard.** Every new Node Lambda targets it, set explicitly in the IaC template.
- **`nodejs22.x` is legacy only.** It is valid for functions that already run on it, and those move to 24.x before the AWS deprecation date of 2027-04-30. Do not start a new function on it.
- **Never target `nodejs26.x`,** including once AWS ships it. Lambda applies runtime updates automatically, so a fresh major is only adopted after it has been generally available on Lambda for a full quarter, and only by a deliberate change to this page. Odd majors (25.x, 27.x) never become Lambda runtimes at all.
Pin `aws-cdk-lib` to an exact version (no `^`, `~`, or `>=`) and let Dependabot keep it current. There is no static "blessed version" — the org standard is the latest release that passes the gates below. Do not add blanket `dependabot.yml` ignore entries for `aws-cdk-lib`; that is how pins rot into carrying known vulnerabilities.
Why exact + automated: the exact pin plus the lockfile gives reproducible builds; weekly Dependabot version updates keep the pin moving; CI (`npm ci` + `cdk synth`) and the dependency-review check reject a bad release at the PR. A release with broken bundled-dep metadata (e.g. 2.254.0) fails `npm ci` on its own bump PR; a release bundling a vulnerable transitive dep fails dependency review. Either way, a bad release never merges — the gates do the vetting, not a frozen number in this document.
aws-cdk-lib bundles transitive dependencies (`inBundle: true`) that npm `overrides` cannot patch. When a bundled dep has a vulnerability, the only fix is advancing to a release that bundles the patched version — treat the alert as a prompt to merge the next Dependabot bump, never as something to dismiss indefinitely.
If a specific release is known-bad, ignore that version only (`ignore: - dependency-name: aws-cdk-lib, versions: ["2.254.0"]`) with a comment explaining why, and remove the entry once a fixed release ships.
- Any externally-consumable URLs (API Gateway endpoints, etc.)
## S3
- Every non-CloudFormation bucket must have `Purpose` and `ManagedBy` tags
- Define lifecycle policies in the IaC template
- Use Glacier Deep Archive for archival data
## README
Every repo must have a README that accurately describes:
- Project architecture
- Lambdas and services
- Data flow
- Configuration requirements
Update the README in the same commit where functionality changes. If a README is missing or outdated when you start working on a project, fix it as part of the current work.