Skip to content

Upgrade to NodeJS 20 (and so also, updating electron from v23 to v31) #3113

Merged
mcginty merged 14 commits intodevelopfrom
node20
Mar 9, 2026
Merged

Upgrade to NodeJS 20 (and so also, updating electron from v23 to v31) #3113
mcginty merged 14 commits intodevelopfrom
node20

Conversation

@bitmold
Copy link
Copy Markdown
Collaborator

@bitmold bitmold commented Feb 24, 2026

In order to upgrade react native versions to support Android 16 (API 36) we need to be using at least nodejs v20. A more extensive update should be undertaken to update to at least node 22, however this requires rebuilding native modules on desktop, Android, and iOS. This is an effective stop gap for the time being.

Tested on Desktop and Mobile, and things seem to work fine.

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Feb 24, 2026

@islathehut

I'm not sure how to update/interact with packages/mobile/android-environment/Dockerfile

You can see that the first contains some kind of versioning/hash for nodejs 18.20.4:

FROM node:18.20.4@sha256:e9ad817b0d42b4d177a4bef8a0aff97c352468a008c3fdb2b4a82533425480df

@bitmold bitmold marked this pull request as ready for review February 24, 2026 05:09
@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Feb 24, 2026

I don't think it's necessary that js-libp2p-noise has it's own .nvmrc file, but in case i'm not seeing something and it does, this needs to be updated in the submodule too:

TryQuiet/js-libp2p-noise#2

(I could imagine it's necessary if for instance you use this library in other contexts (beyond just as a submodule for Quiet) that I'm not aware of)

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Feb 24, 2026

I'll look at these failing e2e tests

@islathehut
Copy link
Copy Markdown
Collaborator

@islathehut

I'm not sure how to update/interact with packages/mobile/android-environment/Dockerfile

You can see that the first contains some kind of versioning/hash for nodejs 18.20.4:

FROM node:18.20.4@sha256:e9ad817b0d42b4d177a4bef8a0aff97c352468a008c3fdb2b4a82533425480df

I updated the dockerfile with the new node docker image. I also added a comment with the dickerhub page for future reference because I had to reorient myself with what this was.

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Feb 28, 2026

@islathehut

So in order to go from electron 23 to 29 (first version that uses node 20) we had to replace assignments of global.webcrypto as node 19 bans this. This is to use @peculiar/webcrypto as global.crypto.

import { Crypto } from '@peculiar/webcrypto'
const webcrypto = new Crypto()

global.crypto = webcrypto

with

import { Crypto } from '@peculiar/webcrypto'
const webcrypto = new Crypto()

Object.defineProperty(global, 'crypto', {
  value: webcrypto,
  writable: true,
})

global.crypto is not directly referenced anywhere in the project

Searching 4185 files for "global.crypto"

~/code/quiet/packages/backend/jestSetup.ts:
    3  
    4  const crypto = new Crypto()
    5: global.crypto = crypto
    6  
    7  setEngine(

~/code/quiet/packages/integration-tests/src/bot/bot.ts:
   15  
   16  const crypto = new Crypto()
   17: global.crypto = crypto
   18  
   19  const webcrypto = new Crypto()

~/code/quiet/packages/integration-tests/src/integrationTests/createJoinCommunity.test.ts:
    7  const crypto = new Crypto()
    8  
    9: global.crypto = crypto
   10  
   11  describe('owner creates community', () => {

~/code/quiet/packages/integration-tests/src/integrationTests/restartApp.test.ts:
   11  const crypto = new Crypto()
   12  
   13: global.crypto = crypto
   14  
   15  describe('restart app without doing anything', () => {

~/code/quiet/packages/integration-tests/src/integrationTests/sendFiles.test.ts:
   16  const crypto = new Crypto()
   17  
   18: global.crypto = crypto
   19  
   20  describe('send message - users are online', () => {

~/code/quiet/packages/integration-tests/src/integrationTests/sendMessages.test.ts:
   12  const crypto = new Crypto()
   13  
   14: global.crypto = crypto
   15  
   16  describe('send message - users go offline and online', () => {

I kept things this way to preserve what the app was doing, and this works...

@islathehut It seems that nodejs 20 and electron's chromium internals both support the standard webcrypto API, so as far as I can tell this is superfluous right now. So is there any reason to not just use the real API and drop @peculiar/webcrypto? It hasn't seen an update in 2 years. Am I missing something?

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Feb 28, 2026

There are some new tests failing! Which I'm working on right now...But apparently electron 29 has a vulnerability - which means we have to upgrade all the way to electron 35+. This seems kind of involved, but can do. It may require recompiling the native libraries on desktop:

Behavior Changed: Native modules now require C++20

Due to changes made upstream, both V8 and Node.js now require C++20 as a minimum version. Developers using native node modules should build their modules with --std=c++20 rather than --std=c++17. Images using gcc9 or lower may need to update to gcc10 in order to compile. See #43555 for more details.

**EDIT: ** fixed the failing tests ....

**EDIT: ** this vulnerability actually doesn't impact quiet desktop...

From: https://nvd.nist.gov/vuln/detail/CVE-2025-55305

"Electron is a framework for writing cross-platform desktop applications using JavaScript, HTML and CSS. In versions below 35.7.5, 36.0.0-alpha.1 through 36.8.0, 37.0.0-alpha.1 through 37.3.1 and 38.0.0-alpha.1 through 38.0.0-beta.6, ASAR Integrity Bypass via resource modification. This only impacts apps that have the embeddedAsarIntegrityValidation and onlyLoadAppFromAsar fuses enabled. Apps without these fuses enabled are not impacted. This issue is fixed in versions 35.7.5, 36.8.1, 37.3.1 and 38.0.0-beta.6."

Since Quiet Desktop doesn't include the embeddedAsarIntegrityValidation and the onlyLoadAppFromAsar fuses, it's not at risk of this vulnerability. So for now, stopping this work at PR at electron v31. Initially node20 mandated we upgrade from electron v23 to 29, and then I stated to go from v29 to v31 on the way to v35 to mitigate this vulnerability. (Upgrading from v29->v31 was trivial because none of the changes in those releases impacted Quiet Dekstop)...

Aside from being desirable to be on a newer, supported, version of electron, you'll eventually have to, for instance electron 35 is needed to use node 22. Also for context, the latest electron is 40, and the lowest supported version is 37.

According to the official breaking changes guide

@bitmold bitmold requested review from islathehut and removed request for holmesworcester February 28, 2026 04:53
…ts. Fixes the e2e stuff that fails on GitHub now that electron has changed versions. Added this step to new nodejs upgrade guide doc
…ditional hardcoded nodejs version config, and makes it easier to upgrade nodejs in the future and to keep tests on dev machines and github CI running with same dependencies
@bitmold bitmold changed the title Upgrade to NodeJS 20 Upgrade to NodeJS 20 (and so also, updating electron from v23 to v31) Mar 1, 2026
Copy link
Copy Markdown
Collaborator

@mcginty mcginty left a comment

Choose a reason for hiding this comment

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

The only blocking change is that .nvmrc file in the workflow, otherwise it seems good with the caveat question about switching to global.crypto.

Comment thread docs/Upgrading Nodejs.md Outdated

The .nvmrc file in the root of the project specifies the node verison that is used. Update this file to the newest version of Node, which will automatically update the node version used by the GitHub action CI scripts found in the `./github` directory.

With [`nmv` installed](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script) run:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
With [`nmv` installed](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script) run:
With [`nvm` installed](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script) run:

Comment thread .github/workflows/e2e-android.yml Outdated
- uses: actions/setup-node@master
with:
node-version: 18.20.4
node-version-file: ".nmvrc"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
node-version-file: ".nmvrc"
node-version-file: ".nvmrc"

Copy link
Copy Markdown
Collaborator Author

@bitmold bitmold Mar 5, 2026

Choose a reason for hiding this comment

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

oh whoops. idk how this worked on the CI here, i think it just defaulted to the correct spelling. I'll fix this

Comment on lines +111 to +114
Object.defineProperty(global, 'crypto', {
value: webcrypto,
writable: true,
})
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I understand from the above comments why this is here, in that you didn't want to swap out crypto implementations at the same time you upgraded Node.

Maybe we should put a TODO here unless you're planning on creating another PR directly after this to switch to the builtin global.crypto implementation?

Copy link
Copy Markdown
Collaborator

@mcginty mcginty left a comment

Choose a reason for hiding this comment

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

Nice!

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Mar 5, 2026

I just pushed a commit with your feedback

From the Slack chat it seems that no one remembers for certain why this lib was used in place of the default one. I will next work on figuring out if it's actually bringing something to the table, and if it's not like i suspect i'll gut it and replace with the standard lib.

Thanks for reviewing !

@mcginty
Copy link
Copy Markdown
Collaborator

mcginty commented Mar 9, 2026

With the build re-triggered (I'm assuming it broke because of GitHub uptime issues), it looks like there are some CI issues to work out still.

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Mar 9, 2026

All set !

@mcginty
Copy link
Copy Markdown
Collaborator

mcginty commented Mar 9, 2026

It looks like there's a vulnerability that CI isn't happy about in https://github.com/TryQuiet/quiet/actions/runs/22786699786/job/66104875820?pr=3113.

@bitmold
Copy link
Copy Markdown
Collaborator Author

bitmold commented Mar 9, 2026

This has been discussed on this PR:
#3113 (comment)

After talking in Slack, it seemed fine to merge this with the understanding that we'd eventually upgrade to electron 35+

@mcginty
Copy link
Copy Markdown
Collaborator

mcginty commented Mar 9, 2026

Ah apologies, I missed that!

@mcginty mcginty merged commit 7fcf314 into develop Mar 9, 2026
43 of 46 checks passed
@bitmold bitmold deleted the node20 branch March 27, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants