Skip to content

refactor(api-service, worker, ws, dashboard): Novu node 22 upgrade#10181

Merged
scopsy merged 8 commits intonextfrom
cursor/novu-node-22-upgrade-3911
Mar 13, 2026
Merged

refactor(api-service, worker, ws, dashboard): Novu node 22 upgrade#10181
scopsy merged 8 commits intonextfrom
cursor/novu-node-22-upgrade-3911

Conversation

@scopsy
Copy link
Contributor

@scopsy scopsy commented Mar 8, 2026

What changed? Why was the change needed?

This PR upgrades the Novu repository to use Node.js 22.22.1 (LTS) from Node.js 20. This update is needed to leverage the latest performance improvements, security enhancements, and language features.

The changes are comprehensive and include:

  • Updating .nvmrc, package.json engine constraints, and @types/node dependencies across the monorepo.
  • Migrating all Dockerfiles to use Node.js 22 base images.
  • Updating GitHub Actions workflows and composite actions to run on Node.js 22.
  • Adjusting development scripts, build targets (e.g., esbuild), and documentation references.

All major services (API, worker, dashboard) have been verified to build successfully with Node.js 22.

Screenshots


Slack Thread

Open in Web Open in Cursor 

- Update .nvmrc to 22.22.1
- Update root package.json engines to >=22 <23
- Update all Dockerfiles (api, worker, ws, webhook, inbound-mail, dashboard, cursor, devcontainer) to node:22-alpine3.20
- Update all GitHub Actions workflows and composite actions to use node 22.22.1
- Update @types/node from ^20.x to ^22.0.0 across all packages
- Update dev-environment-setup.sh to install v22.22.1
- Update esbuild target from node20 to node22
- Update documentation (AGENTS.md, CLAUDE.md, CONTRIBUTING.md, bug report template)
- Regenerate pnpm-lock.yaml

Co-authored-by: Dima Grossman <dima@grossman.io>
@cursor
Copy link
Contributor

cursor bot commented Mar 8, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@netlify
Copy link

netlify bot commented Mar 8, 2026

Deploy preview added

Name Link
🔨 Latest commit ccb4bf5
🔍 Latest deploy log https://app.netlify.com/projects/dashboard-v2-novu-staging/deploys/69b3e941ccce23000807a815
😎 Deploy Preview https://deploy-preview-10181.dashboard-v2.novu-staging.co
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

Hey there and thank you for opening this pull request! 👋

We require pull request titles to follow specific formatting rules and it looks like your proposed title needs to be adjusted.

Your PR title is: refactor(api-service, worker, ws, dashboard): Novu node 22 upgrade

Requirements:

  1. Follow the Conventional Commits specification
  2. As a team member, include Linear ticket ID at the end: fixes TICKET-ID or include it in your branch name

Expected format: feat(scope): Add fancy new feature fixes NOV-123

Details:

PR title must end with 'fixes TICKET-ID' (e.g., 'fixes NOV-123') or include ticket ID in branch name

Resolved Alpine version conflicts in all Dockerfiles by combining
Node 22 upgrade (ours) with Alpine 3.21 bump (next): node:22-alpine3.21

Co-authored-by: Dima Grossman <dima@grossman.io>
@scopsy scopsy changed the title Novu node 22 upgrade refactor(api-service, worker, ws, dashboard): Novu node 22 upgrade Mar 8, 2026
@scopsy scopsy marked this pull request as ready for review March 8, 2026 10:18
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The pull request upgrades Node.js from 20 to 22 across the repository. It updates Docker base images, devcontainer ARGs, GitHub Actions and workflow node-version values to 22.22.1, bumps .nvmrc and install scripts, changes engines.node to ">=22 <23", updates many devDependencies (@types/node), adjusts test commands and Mocha configs to add --no-experimental-strip-types, and changes an esbuild target from node20 to node22. These updates are applied across apps, packages, workflows, scripts, and documentation.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: upgrading Node.js from version 20 to version 22 across multiple services (api-service, worker, ws, dashboard).
Description check ✅ Passed The description clearly explains the upgrade from Node.js 20 to 22.22.1 (LTS), lists the comprehensive changes made, and mentions verification of major services.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/dev-environment-setup.sh (1)

268-288: ⚠️ Potential issue | 🟠 Major

Upgrade existing Node 20 installs instead of only checking for a missing binary.

install_node() now targets v22.22.1, but it still skips installation whenever any node binary is present. A developer who already has Node 20 installed will get the “already installed” path and stay on an unsupported runtime even though the repo now requires >=22 <23. Please compare the current version before deciding to skip.

Suggested fix
 install_node () {
     NODE_JS_VERSION="v22.22.1"
+    REQUIRED_NODE_MAJOR="22"
 
     SKIP="$(check_nvm)"
 
     if [[ -z "$SKIP" ]]; then
         TEST_CMD=$(execute_command_without_error_print "node --version")
-        if [[ -z "$TEST_CMD" ]] || [[ "$TEST_CMD" == "zsh: command not found: node" ]]; then
+        if [[ -z "$TEST_CMD" ]] || [[ "$TEST_CMD" == "zsh: command not found: node" ]] || [[ "$TEST_CMD" != v${REQUIRED_NODE_MAJOR}.* ]]; then
             installing_dependency "Node.js $NODE_JS_VERSION"
 
             nvm install $NODE_JS_VERSION
+            nvm alias default $NODE_JS_VERSION
             TEST_NODE_CMD=$(execute_command_without_error_print "node --version")
 
             if [[ -z "$TEST_NODE_CMD" ]] || [[ "$TEST_NODE_CMD" == "zsh: command not found: node" ]]; then
                 error_message "Node.js"
 	    else
                 success_message "Node.js $NODE_JS_VERSION"
             fi
          else
             already_installed_message "Node.js $NODE_JS_VERSION"
          fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/dev-environment-setup.sh` around lines 268 - 288, install_node
currently treats any present node binary as "already installed" and skips
upgrades; change it to read the existing version via
execute_command_without_error_print "node --version" (handling "command not
found" as before), parse the semantic version, and compare against
NODE_JS_VERSION (v22.22.1) so that if the installed major/minor is outside the
required range (>=22 <23) the function proceeds to install/upgrade via nvm
install and verify with TEST_NODE_CMD; keep check_nvm logic but ensure after nvm
install you also set/use the installed version (alias/default) and call
success_message or error_message based on the post-install version check.
🧹 Nitpick comments (1)
apps/ws/Dockerfile (1)

1-1: Consider pinning the Docker Node patch version here too.

.nvmrc/CI are being standardized on 22.22.1, but node:22-alpine3.21 will float to whatever 22.x patch is current later on. That reintroduces environment skew for the exact upgrade this PR is trying to lock down. If patch-level reproducibility matters, pin the image to the same Node patch or a digest.

Also applies to: 50-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ws/Dockerfile` at line 1, The FROM line in the Dockerfile currently uses
a floating Node patch tag ("FROM node:22-alpine3.21"); change it to a pinned
Node patch (e.g., "node:22.22.1-alpine3.21") or use the image digest to ensure
patch-level reproducibility, and apply the same pinning to any other Dockerfiles
with the same pattern (the other "FROM node:22-alpine3.21" occurrence noted in
the review).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/Dockerfile`:
- Line 1: The Dockerfile uses floating Node tags ("FROM node:22-alpine3.21")
which can drift; update each FROM occurrence that references
"node:22-alpine3.21" (both the top-level FROM and the later FROM at the other
stage) to the pinned patch "node:22.22.1-alpine3.21" so the container build
matches .nvmrc/migration versions and ensures reproducible builds.

In `@apps/dashboard/dockerfile`:
- Line 1: Update the Dockerfile image tags to match the exact Node patch from
.nvmrc: replace the floating "node:22-alpine3.21" occurrences (e.g., the FROM
line and the second occurrence around Line 28) with the pinned patch
"node:22.22.1-alpine3.21" so the dashboard container matches the project's
.nvmrc Node version.

In `@apps/inbound-mail/Dockerfile`:
- Line 1: The Dockerfile base image is floating (FROM node:22-alpine3.21);
update that FROM line to pin the Node patch to 22.22.1 (use
node:22.22.1-alpine3.21) so it matches .nvmrc/CI, and then re-run the repository
check (the ripgrep command provided in the review) to ensure no other floating
Node 22 references remain; change the literal "node:22-alpine3.21" to
"node:22.22.1-alpine3.21" in the Dockerfile.

---

Outside diff comments:
In `@scripts/dev-environment-setup.sh`:
- Around line 268-288: install_node currently treats any present node binary as
"already installed" and skips upgrades; change it to read the existing version
via execute_command_without_error_print "node --version" (handling "command not
found" as before), parse the semantic version, and compare against
NODE_JS_VERSION (v22.22.1) so that if the installed major/minor is outside the
required range (>=22 <23) the function proceeds to install/upgrade via nvm
install and verify with TEST_NODE_CMD; keep check_nvm logic but ensure after nvm
install you also set/use the installed version (alias/default) and call
success_message or error_message based on the post-install version check.

---

Nitpick comments:
In `@apps/ws/Dockerfile`:
- Line 1: The FROM line in the Dockerfile currently uses a floating Node patch
tag ("FROM node:22-alpine3.21"); change it to a pinned Node patch (e.g.,
"node:22.22.1-alpine3.21") or use the image digest to ensure patch-level
reproducibility, and apply the same pinning to any other Dockerfiles with the
same pattern (the other "FROM node:22-alpine3.21" occurrence noted in the
review).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 93bc2dd1-de16-4d7d-a2d1-c21cc1050cd9

📥 Commits

Reviewing files that changed from the base of the PR and between 4f1939b and 99be523.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (50)
  • .cursor/Dockerfile
  • .devcontainer/Dockerfile
  • .github/ISSUE_TEMPLATE/bug_report.yml
  • .github/actions/setup-project-minimal/action.yml
  • .github/actions/setup-project/action.yml
  • .github/workflows/community-label.yml
  • .github/workflows/contributor-checks.yml
  • .github/workflows/deploy.yml
  • .github/workflows/issue-label.yml
  • .github/workflows/prepare-enterprise-self-hosted-release.yml
  • .github/workflows/prepare-self-hosted-release.yml
  • .github/workflows/preview-packages.yml
  • .github/workflows/release-packages.yml
  • .github/workflows/reusable-dashboard-e2e.yml
  • .nvmrc
  • AGENTS.md
  • CLAUDE.md
  • CONTRIBUTING.md
  • apps/api/Dockerfile
  • apps/api/package.json
  • apps/dashboard/dockerfile
  • apps/inbound-mail/Dockerfile
  • apps/inbound-mail/package.json
  • apps/webhook/Dockerfile
  • apps/webhook/package.json
  • apps/worker/Dockerfile
  • apps/worker/package.json
  • apps/ws/Dockerfile
  • apps/ws/package.json
  • enterprise/packages/ai/package.json
  • enterprise/packages/api/package.json
  • enterprise/packages/auth/package.json
  • enterprise/packages/billing/package.json
  • enterprise/packages/shared-services/package.json
  • enterprise/packages/translation/package.json
  • libs/automation/package.json
  • libs/dal/package.json
  • libs/internal-sdk/examples/package.json
  • libs/testing/package.json
  • package.json
  • packages/framework/package.json
  • packages/js/package.json
  • packages/nextjs/package.json
  • packages/novu/src/commands/email/bundler/schema-extractor.ts
  • packages/react-native/package.json
  • packages/react/package.json
  • packages/stateless/package.json
  • playground/nestjs/package.json
  • playground/nextjs/package.json
  • scripts/dev-environment-setup.sh

- Pin Docker base images to node:22.22.1-alpine3.21 for reproducible builds
- Fix install_node() to check existing version and upgrade from Node 20

Co-authored-by: Dima Grossman <dima@grossman.io>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
scripts/dev-environment-setup.sh (1)

1-1: Consider: Shebang declares POSIX sh but script uses Bash/Zsh features.

The script uses #!/bin/sh but relies on [[ ]] syntax (lines 274, 276, and many others) which is not POSIX-compliant. While this works on macOS where /bin/sh often supports these features, consider updating the shebang to #!/bin/bash or #!/bin/zsh for correctness.

This is a pre-existing issue, not introduced by this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/dev-environment-setup.sh` at line 1, The script's shebang (#!/bin/sh)
is incorrect because the script uses Bash/Zsh-only test syntax like [[ ... ]]
(seen around the [[ ]] usages at lines marked 274 and 276); update the shebang
to a Bash-compatible interpreter (for portability prefer using /usr/bin/env
bash) so the [[ ... ]] tests and other Bash features run correctly, or
alternatively convert all [[ ... ]] usages to POSIX-compliant [ ... ] tests if
you must keep /bin/sh.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/dev-environment-setup.sh`:
- Line 1: The script's shebang (#!/bin/sh) is incorrect because the script uses
Bash/Zsh-only test syntax like [[ ... ]] (seen around the [[ ]] usages at lines
marked 274 and 276); update the shebang to a Bash-compatible interpreter (for
portability prefer using /usr/bin/env bash) so the [[ ... ]] tests and other
Bash features run correctly, or alternatively convert all [[ ... ]] usages to
POSIX-compliant [ ... ] tests if you must keep /bin/sh.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c06b0852-b9b6-4cfd-a7ce-2e21997be4d5

📥 Commits

Reviewing files that changed from the base of the PR and between bd1cfa8 and e7df8ee.

📒 Files selected for processing (7)
  • apps/api/Dockerfile
  • apps/dashboard/dockerfile
  • apps/inbound-mail/Dockerfile
  • apps/webhook/Dockerfile
  • apps/worker/Dockerfile
  • apps/ws/Dockerfile
  • scripts/dev-environment-setup.sh
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/webhook/Dockerfile
  • apps/inbound-mail/Dockerfile
  • apps/ws/Dockerfile
  • apps/dashboard/dockerfile

node:22.22.1-alpine3.21 doesn't exist on Docker Hub. The available
Alpine versions for Node 22.22.1 are 3.22 and 3.23. Updated all
Dockerfiles to use node:22.22.1-alpine3.22.

Co-authored-by: Dima Grossman <dima@grossman.io>
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:36 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:37 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:37 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:37 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 10:49 — with GitHub Actions Inactive
@scopsy scopsy deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Active
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Inactive
@scopsy scopsy temporarily deployed to staging-apse1 March 12, 2026 11:17 — with GitHub Actions Inactive
@scopsy scopsy merged commit b374bd8 into next Mar 13, 2026
31 of 32 checks passed
@scopsy scopsy deleted the cursor/novu-node-22-upgrade-3911 branch March 13, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants