Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/setup-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ runs:
steps:
- uses: actions/setup-node@master
with:
node-version: 18.20.4
node-version-file: ".nvmrc"

- name: Set up Python 3.12
uses: actions/setup-python@v5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

- 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


- name: Install dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

- uses: actions/setup-node@master
with:
node-version: 18.20.4
node-version-file: ".nvmrc"

- name: Install dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.20.4
20.20.0
121 changes: 121 additions & 0 deletions docs/Upgrading Nodejs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Upgrading to new Versions of NodeJS

1. `.nvmrc`

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:


```bash
nvm install # installs the latest nvm on your machine if it's not present
nvm use # set it as the default node version
```

You should see output like this:

```
Now using Node v20.20.0 (npm 10.8.2) ~/.local/share/nvm/v20.20.0/bin/node
```

The `node` version is the version specified in `.nvmrc`, make note of the corresponding `npm` verison, in this case `10.8.2`.

2. Updating `package.json`

In the root `package.json` update the `engine` and `volta` with the `node` version you specified and the `npm` version from above:

```json
"engines": {
"node": "20.20.0",
"npm": "10.8.2"
}
```

```json
"volta": {
"node": "20.20.0",
"npm": "10.8.2"
}
```

3. Readme Documentation

Update `packages/desktop/README.md` and `packages/mobile/README.md` and any other documentation with your new `node` version.

4. Android Docker File

Open https://hub.docker.com/layers/library/node/20.20.0/ with your node verison. Copy and paste the "Index Digest" text strating with `sha256:`

Then edit `pacakges/mobile/android-environment/Dockerfile`

```Dockerfile
FROM node:20.20.0@sha256:65b74d0fb42134c49530a8c34e9f3e4a2fb8e1f99ac4a0eb4e6f314b426183a2
```

- Change the `node` version to the new version
- After the `@` sign update the digest with the value copied above from the webpage

5. If necessary, to support the new version, obtain new `classic-level` binaries for each platofrm + architecture that are linked against the new nodejs version. This will be needed if there are brekaing changes to the `n-api` the "node API" used for npm modules with native code in your new nodejs release. `classic-level` might have to be recompiled by hand. Update:

- `packages/backend-bundle/deps/darwin/universal/classic-level/classic-level.node` (NOTE that this is a ["Mach-O FAT binary"](https://en.wikipedia.org/wiki/Fat_binary#Mach-O_and_Mac_OS_X) containing executable code for macOS that can is capable of running on **both** ARM and Intel macs)
- `packages/backend-bundle/deps/linux/x64/classic-level/classic_level.node` for Intel based Linux machines
- `packages/backend-bundle/depswin32/x64/classic-level/classic_level.node` for Intel based Windows machines. *As of this writing Quiet doesn't support ARM based Windows PCs...*
- `packages/mobile/nodejs-assets/deps/android/arm64/classic-level/classic_level.node` This is the binary for Android devices with 64 bit ARM processors. It won't work on older 32 bit Android ARM processors, aka devices wiht the `armeabi-v7a` ABI which are still found in the wild. It won't work in android emulators that are running on Intel based hosts, but can run fine on emulators with a 64 bit ARM (such as newer Apple Silicon macs). In order to be submitted in the play store this binary needs to be 16-bit aligned, which happens automatically when you compile it with Android NDK versions 28 and higher.
- `packages/mobile/nodejs-assets/deps/ios/universal/classic-level/classic_level.node` This is the iOS binary. It's also technically a Mach-O FAT binary, but currently only supports one architecture which is the `arm64` one for physical iPhones, but in theory there should be a binary (either seperately or as a FAT binary) supporting the `arm64-simulator` architecture which will let you run Quiet in the iPhone simulator on Apple Silicon macs...
- `cp -f` the new `packages/mobile/nodejs-assets/deps/ios/universal/classic-level/classic_level.node` from the last step to `packages/mobile/ios/classic-level.framework/classic-level` (overwrite the file here with the `.node` file from the last step but **don't** include the file extension...)

See `packages/mobile/docs/building-classic-level-android.md` for help on recompiling `classic-level` against the headers in nodejs mobile.


6. Update the nodejs backend on iOS and Android, if necessary. **This is different from the version of nodejs that react native uses.** This version of nodejs is used to run custom nodejs modules on these platforms, it's what's used to run the `classic-level` binary. This only should happen if you had to do the last step...

*comming soon...*

6. Update `node` command line flags, if necessary

New versions of add/remove command line flags. If you need to make this change update:

- the various tests in `packages/backend/package.json`
- `packages/desktop/src/main/main.ts` for the Desktop electron app
- If you had to update the mobile dependencies for `classic-level` in steps 5 and 6, then also update:
- Update the args in `pacakges/mobile/android/app/src/main/java/com/quietmobile/Backend/BackendWorker.kt`'s `fun` `startNodeProjectWithArguments`
- `packages/mobile/ios/NodeJsMobile/RNNodeJsMobile.m`'s `-(void)callStartNodeProject:(NSString *)input`. Note that on iOS this is defined in the variable `nodeArguements` twice:


```m
NSString* dlopenoverridePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@/%@", NODEJS_PROJECT_RESOURCE_PATH, NODEJS_DLOPEN_OVERRIDE_FILENAME] ofType:@""];

// Check if the file to override dlopen lookup exists, for loading native modules from the Frameworks.
if(!dlopenoverridePath)
{
nodeArguments = [NSMutableArray arrayWithObjects:
@"node",
@"--experimental-global-customevent",
srcPath,
nil
];

[nodeArguments addObjectsFromArray:args];
} else {
nodeArguments = [NSMutableArray arrayWithObjects:
@"node",
@"--experimental-global-customevent",
@"-r",
dlopenoverridePath,
srcPath,
nil
];

[nodeArguments addObjectsFromArray:args];
```
7. Update `electron`

Migrate `packages/desktop/package.json` to an electron version that ships with the new node verison.

- You can see each major electron release's nodejs [here](https://releases.electronjs.org/release?channel=stable)
- Pay careful attention to breaking changes within electron releases. APIs can be removed which will make your project fail to build. But also, and more subtly, the behavior of a certain API may change causing Quiet to build and perhaps seem OK, but something is now behaving differently and/or incorrectly.
- Upgrade the `selenium-webdriver` and the `electron-chromedriver` modules in `packages/e2e-tests/package.json`. `electron-chromedriver` should match the major version of `electron` that you just migrated to in the `desktop` package.

8. Bootsrap

Run `npm run bootstrap` and fix whatever just got broken with the new `node` version.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"stop:qss": "cd ./3rd-party/qss && pnpm run run:app docker:down:complete"
},
"engines": {
"node": "18.20.4",
"npm": "10.7.0"
"node": "20.20.0",
"npm": "10.8.2"
},
"devDependencies": {
"husky": "^9.0.11",
Expand All @@ -38,8 +38,8 @@
"typescript": "^4.9.5"
},
"volta": {
"node": "18.20.4",
"npm": "10.7.0"
"node": "20.20.0",
"npm": "10.8.2"
},
"dependencies": {
"unicode-emoji-json": "^0.8.0"
Expand Down
14 changes: 8 additions & 6 deletions packages/backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@
"lint": "npm run lint:no-fix -- --fix",
"lint-ci": "npm run lint:no-fix",
"lint-staged": "lint-staged --no-stash",
"test-nest": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --detectOpenHandles --forceExit ./src/nest/**/*.spec.ts",
"test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" DEBUG=ipfs:*,backend:* jest --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\" --detectOpenHandles --forceExit",
"test-ci": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" jest --runInBand --colors --ci --silent --verbose --detectOpenHandles --forceExit --testPathIgnorePatterns \"/node_modules/\" --testPathIgnorePatterns \"/dist/\" --testPathIgnorePatterns \"src/nest/.*\\.tor\\.spec\\.(t|j)s$\" --testPathIgnorePatterns \"src/nest/ipfs-file-manager/big-files\\.long\\.spec\\.ts$\"",
"test-ci-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" jest --runInBand --colors --ci --verbose --detectOpenHandles --forceExit ./src/nest/**/*.tor.spec.ts",
"test-ci-long-running": "cross-env DEBUG=backend:* NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" jest --colors --ci --verbose --detectOpenHandles --forceExit ./src/nest/**/*.long.spec.ts",
"test-connect": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" DEBUG='libp2p:websockets*' jest ./src/nodeTest/* --verbose",
"test-connect-ci": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" jest ./src/nodeTest/* --colors --ci --silent --verbose",
"test-replication-no-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" ts-node -v && cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 200 --entriesCount 1000 --no-useTor",
"test-replication-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 500 --entriesCount 1000 --useTor",
"test-it": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --experimental-global-customevent\" DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\" --",
"test-nest": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --detectOpenHandles --forceExit ./src/nest/**/*.spec.ts",
"test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" DEBUG=ipfs:*,backend:* jest --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\" --detectOpenHandles --forceExit",
"test-ci": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --runInBand --colors --ci --silent --verbose --detectOpenHandles --forceExit --testPathIgnorePatterns \"/node_modules/\" --testPathIgnorePatterns \"/dist/\" --testPathIgnorePatterns \"src/nest/.*\\.tor\\.spec\\.(t|j)s$\" --testPathIgnorePatterns \"src/nest/ipfs-file-manager/big-files\\.long\\.spec\\.ts$\"",
"test-ci-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --runInBand --colors --ci --verbose --detectOpenHandles --forceExit ./src/nest/**/*.tor.spec.ts",
"test-ci-long-running": "cross-env DEBUG=backend:* NODE_OPTIONS=\"--experimental-vm-modules\" jest --colors --ci --verbose --detectOpenHandles --forceExit ./src/nest/**/*.long.spec.ts",
"test-connect": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" DEBUG='libp2p:websockets*' jest ./src/nodeTest/* --verbose",
"test-connect-ci": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest ./src/nodeTest/* --colors --ci --silent --verbose",
"test-replication-no-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" ts-node -v && cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 200 --entriesCount 1000 --no-useTor",
"test-replication-tor": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 500 --entriesCount 1000 --useTor",
"test-it": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\" --",
"rmDist": "rimraf lib/"
},
"repository": {
Expand Down Expand Up @@ -133,7 +133,7 @@
"@nestjs/platform-express": "^10.2.10",
"@orbitdb/core": "file:../../3rd-party/orbitdb",
"@paralleldrive/cuid2": "^2.2.2",
"@peculiar/webcrypto": "1.4.3",
"@peculiar/webcrypto": "1.5.0",
"@quiet/common": "^2.0.2-alpha.1",
"@quiet/identity": "^2.0.2-alpha.2",
"@quiet/logger": "^2.0.2-alpha.0",
Expand Down
9 changes: 7 additions & 2 deletions packages/backend/src/backendManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,13 @@ export const runBackendDesktop = async (secret: string) => {

const isDev = process.env.NODE_ENV === 'development'
const webcrypto = new Crypto()
// @ts-ignore
global.crypto = webcrypto

// https://github.com/lobehub/lobehub/issues/5315#issuecomment-2572703223
Object.defineProperty(global, 'crypto', {
value: webcrypto,
writable: true,
})

validateOptions(options)
const resourcesPath = options.resourcesPath.trim()
if (!secret) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI

async onModuleInit() {
const webcrypto = new Crypto()
// @ts-ignore
global.crypto = webcrypto
// https://github.com/lobehub/lobehub/issues/5315#issuecomment-2572703223
Object.defineProperty(global, 'crypto', {
value: webcrypto,
writable: true,
})
Comment on lines +112 to +115
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?


setEngine(
'newEngine',
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Here are the steps:

1. Install `patch` via your Linux package manager (you can skip this step on Mac because it is already installed)

2. Use `Node 18.20.4` and `npm 10.7.0`. We recommend [nvm](https://github.com/nvm-sh/nvm) or [volta](https://volta.sh/) for easily switching Node versions, and if this README gets out of date you can see the actual version used by CI [here](https://github.com/TryQuiet/quiet/blob/master/.github/actions/setup-env/action.yml). If you are using nvm, you can run `nvm use` in the project's root to switch to the correct version.
2. Use `Node 20.20.0` and `npm 10.8.2`. We recommend [nvm](https://github.com/nvm-sh/nvm) or [volta](https://volta.sh/) for easily switching Node versions, and if this README gets out of date you can see the actual version used by CI [here](https://github.com/TryQuiet/quiet/blob/master/.nvmrc). If you are using nvm, you can run `nvm use` in the project's root to switch to the correct version.

3. Install python3 and setuptools through your preferred method. (used by node-gyp)

Expand Down
Loading
Loading