A more modern successor for flatpak-npm-generator and flatpak-yarn-generator, for Node 10+ only. Supports npm, yarn, and pnpm. (For Node 8, use flatpak-npm-generator and flatpak-yarn-generator.)
NOTE: --xdg-layout was recently changed to be the default. In the stark
majority of cases, this needed to be passed, so you can now omit using it
explicitly. If you're on a relatively old Electron version before this was
required, however, you can disable it explicitly via --no-xdg-layout.
- flatpak-builder 1.1.2 or newer
- Python 3.11+.
- pipx (recommended) or pip (both of these are usually available in your distro repositories, the latter is often included with Python installs).
The easiest way to use this tool is to install it via pipx, the officially recommended way of installing Python packages, by running the following:
$ pipx install git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node
If you encounter a JSONDecodeError from pipx while installing it, try
deleting the local pipx virtuanlenv in ~/.local/share/pipx on Linux.
There are two examples provided for how to use flatpak-node-generator:
vanilla-quick-start- A Flatpak of electron-quick-start. It uses npm for package management and a rather basic Electron workflow. (Current on the Electron 4 version.)webpack-quick-start- A Flatpak of electron-webpack-quick-start. It uses yarn for package management and electron-builder + webpack.fiddle-yarn-berry- A Flatpak of electron-fiddle. It uses yarn/berry for package management and a rather basic Electron workflow.
Both manifests have comments to highlight their differences, so you can mix and match to e.g. get npm with electron-builder.
usage: flatpak-node-generator [-h] [-o OUTPUT] [-r] [-R RECURSIVE_PATTERN] [--registry REGISTRY] [--no-trim-index]
[--no-devel] [--no-requests-cache]
[--max-parallel MAX_PARALLEL]
[--retries RETRIES] [-P] [-s] [-S SPLIT_SIZE]
[--node-chromedriver-from-electron NODE_CHROMEDRIVER_FROM_ELECTRON]
[--electron-ffmpeg {archive,lib}]
[--electron-node-headers]
[--nwjs-version NWJS_VERSION]
[--nwjs-node-headers] [--nwjs-ffmpeg]
[--no-xdg-layout]
[--node-sdk-extension NODE_SDK_EXTENSION]
{npm,yarn,pnpm} lockfile
Flatpak Node generator
positional arguments:
{npm,yarn,pnpm}
lockfile The lockfile path (package-lock.json, yarn.lock, or pnpm-lock.yaml)
options:
-h, --help show this help message and exit
-o, --output OUTPUT The output sources file
-r, --recursive Recursively process all files under the lockfile directory with the lockfile basename
-R, --recursive-pattern RECURSIVE_PATTERN
Given -r, restrict files to those matching the given pattern.
--registry REGISTRY The registry to use (npm/pnpm)
--no-trim-index Don't trim npm package metadata (npm only)
--no-devel Don't include devel dependencies (npm/pnpm)
--no-requests-cache Disable the requests cache
--max-parallel MAX_PARALLEL
Maximium number of packages to process in parallel
--retries RETRIES Number of retries of failed requests
-P, --no-autopatch Don't automatically patch Git sources from package*.json
-s, --split Split the sources file to fit onto GitHub.
-S, --split-size SPLIT_SIZE
If splitting the sources file, split at this size in KB. Default is 49000 KB.
--node-chromedriver-from-electron NODE_CHROMEDRIVER_FROM_ELECTRON
Use the ChromeDriver version associated with the given Electron version for node-chromedriver
--electron-ffmpeg {archive,lib}
Download prebuilt ffmpeg for matching electron version
--electron-node-headers
Download the electron node headers
--nwjs-version NWJS_VERSION
Specify NW.js version (will use latest otherwise)
--nwjs-node-headers Download the NW.js node headers
--nwjs-ffmpeg Download prebuilt ffmpeg for current NW.js version
--no-xdg-layout Don't use the XDG layout for caches
--node-sdk-extension NODE_SDK_EXTENSION
Flatpak node SDK extension (e.g. org.freedesktop.Sdk.Extension.node24//25.08)
flatpak-node-generator takes a package manager (npm, yarn, or pnpm), and a path to a lockfile for that package manager. It writes an output sources file (default is generated-sources.json) containing all the sources needed for the given package manager.
If you're on npm or pnpm and you don't want to include devel dependencies, pass --no-devel.
For npm, also pass --production to npm install itself.
If you're using npm, you must run this script when the node_modules directory is NOT present.
If you generate the generated-sources.json in CI, you can do this by passing --package-lock-only
to npm install.
flatpak-node-generator will cache many API responses and archives from the server to speed up
subsequent runs. You can disable this using --no-requests-cache, and it can be cleared via
rm -rf ${XDG_CACHE_HOME:-$HOME/.cache}/flatpak-node-generator.
If your Node app has too many dependencies (particularly with npm), the generated-sources.json
may be larger than GitHub's maximum size. In order to circumvent this, you can pass -s, which
will write multiple files (generated-sources.0.json, generated-sources.1.json, etc) instead of
one, each smaller than the GitHub limit.
If your app depends on node-chromedriver, then flatpak-node-generator will download it
to the directory $FLATPAK_BUILDER_BUILDDIR/flatpak-node/chromedriver. You need to
do two things in order to utilize this:
- Add
CHROMEDRIVER_SKIP_DOWNLOAD=trueto your environment variables. - Add
$FLATPAK_BUILDER_BUILDDIR/flatpak-node/chromedriverto your PATH.
It might look like this:
build-options:
append-path: '/usr/lib/sdk/node10/bin:/run/build/MY-MODULE/flatpak-node/chromedriver'
env:
CHROMEDRIVER_SKIP_DOWNLOAD: 'true'
# ...In addition, the default ChromeDriver only is available for x64. If you need to build
on other platforms, you can use the ChromeDriver binaries that are compiled by Electron
and distributed with their releases. To do this, pass
--node-chromedriver-from-electron AN_ELECTRON_VERSION to use the ChromeDriver given with
that Electron version. Note that you may not necessarily want to use a version here that
corresponds to the Electron version your app is using; many apps stay on older Electron
versions but may use newer ChromeDriver functionality.
electron-chromedriver will be handled automatically, but make sure ELECTRON_CACHE is
set as show in the quickstart examples.
Sometimes you might have multiple lockfiles in a single source tree that need to have sources
generated for them. For this, you can pass -r, which will find all the lockfiles with the
name of the lockfile path you gave it in the same directory.
E.g. for instance, if you run:
flatpak-node-generator yarn -r ~/my-project/yarn.lock
flatpak-node-generator will find all files named yarn.lock inside of my-project.
If you want to match only certain lockfiles, pass -R pattern too:
flatpak-node-generator yarn -r ~/my-project/yarn.lock -R 'something*/yarn.lock' -R 'another*/yarn.lock'
In this case, only lockfiles matching something*/yarn.lock or another*/yarn.lock will be used.
With yarn, we're done here. However, npm has a few more curveballs you need to know about.
If you have any Git sources in your package.json, then they need to be patched to point to the Flatpak-downloaded Git repos. flatpak-node-generator normally takes care of this patching automatically. However, in the case of recursive package.jsons, this is a little different.
Say you have the following project directory structure:
my-project/
node_modules/
my-nested-project/
package.json
package-lock.json
package-lock.json
my-nested-project doesn't ship built dependencies, so you need to build them yourself.
Therefore, you might run something like this in your Flatpak build commands:
npm install ...in the root directory.npm install ...in the my-nested-project directory.npm run buildor whatever build command in the my-nested-project directory.
However, if my-nested-project uses a Git source, then flatpak-node-generator will try to patch
it out...except my-nested-project's directory won't exist until you run the first npm install,
therefore the patch command and your build will fail.
In order to work around this, you need to pass -P / --no-autopatch to flatpak-node-generator.
This will disable the automated patching. Then, you'll need to call the scripts to patch your
package files manually. so a new build-commands might look like this:
flatpak-node/patch.sh.npm install ...in the root directory.flatpak-node/patch/node_modules/my-nested-project.shnpm install ...in the my-nested-project directory.npm run buildor whatever build command in the my-nested-project directory.
In short, flatpak-node-generator will generate a patch script named
flatpak-node/patch/path-to-package-lock.json; if package-lock.json is in the root directory,
then the name will just be patch.sh. Here these will be called manually, thereby ensuring
that the files that need to be patched will already exist.
(In addition, flatpak-node-generator will generate flatpak-node/patch-all.sh, which is what is
automatically run by default when you don't pass -P.)
If you want to build for ARM or ARM64 with electron-builder, there are two important things to note:
- For ARM in particular, electron-builder will misdetect the architecture and give
an error about it being unsupported. To work around this, you have to pass the
architecture manually to electron-builder. flatpak-node-generator will create a script by adding
it as an entry to the sources file. During the build process script will be created at
flatpak-node/electron-builder-arch-args.shso it can be sourced to set the$ELECTRON_BUILDER_ARCH_ARGSenvironment variable. Then, this variable can be passed to the electron-builder command. - For both ARM and ARM64, the electron-builder output directory will contain the architecture in its name.
Both of these cases are handled by the electron-webpack-quick-start example.
Some node/electron versions are binary incompatible and require rebuilding of
native node dependencies for electron. In offline mode, it may result in broken
ABI. If you are seeing errors like The module 'something.node' was compiled against a different Node.js version, then pass --electron-node-headers
option to flatpak-node-generator and set npm_config_nodedir to
flatpak-node/node-gyp/electron-current.
Note: Setting npm_config_nodedir should not be necessary when using XDG-compliant
cache directories layout (the default, unless disabled via --no-xdg-layout).
Some tools like electron-rebuild don't properly respect the XDG spec however. In this case, as a workaround, you might need to symlink the cache directory. For example:
build-commands:
- |
ln -s $XDG_CACHE_HOME/node-gyp $HOME/.electron-gyp
npm run build(Note that the build command must be ran as part of the same command as ln,
i.e. it won't work if you run them as separate commands.)
If your app needs separate ffmpeg for matching electron version, add
--electron-ffmpeg=archive option to flatpak-node-generator. This will put
ffmpeg-$suffix.zip alongside electron in the cache directory.
By defualt, the ffmpeg that Electron ships with has proprietary codecs built in
like AAC and H.264. If you don't need these, you can pass
--electron-ffmpeg=lib to flatpak-node-generator. This will download
a patent-clean ffmpeg binary to flatpak-node/libffmpeg.so, which you can then
use to overwrite the default Electron ffmpeg, e.g.:
- 'install -Dm 755 flatpak-node/libffmpeg.so -t /app/electron-webpack-quick-start'An short example of this is again in the electron-webpack-quick-start
This scripts assumes NW.js is used if the lockfile contains nw-builder package.
Unlike Electron, NW.js engine version is not reflected in NPM package.
- If the app you're building uses specific NW.js version, specify it
using
--nwjs-versionargument - If any NW.js version will suffice, this script will use latest;
the version number will be stored in
flatpak-node/nwjs-versionfile. You can tellnw-builderto use this version by passing-varg tonwbuild:nwbuild -v $(<$FLATPAK_BUILDER_BUILDDIR/flatpak-node/nwjs-version)
We use Poetry for local development. You can set up the local virtualenv via:
$ poetry install
After making any changes, you can re-run all the checks & unit tests via:
$ poetry run poe check
or invoke pytest manually:
$ poetry run pytest -n auto
The tests need Flathub set up and certain SDK extensions installed:
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak --user install -y flathub org.freedesktop.{Platform,Sdk{,.Extension.node{14,16,18}}}//22.08
flatpak --user install -y flathub org.freedesktop.{Platform,Sdk{,.Extension.node{20,22}}}//24.08Note that these tests can take up quite a bit of space in /tmp, so if you hit No space left on device errors, try expanding /tmp or changing $TMPDIR.
A few utility scripts are included in the tools directory:
lockfile-utils.shhas a few different helpers for working with the lockfiles used by test packages intests/data/packages:lockfile-utils.sh update-lockfile PACKAGE-MANAGER PACKAGEwill recreate the lockfile for the given package manager (one ofnpm-14for Node 14's NPM,npm-16for Node 16's npm, oryarn).lockfile-utils.sh peek-cache PACKAGE-MANAGER PACKAGEwill install the dependencies from the corresponding lockfile and then extract the resulting package cache (npm) or mirror directory (yarn), for closer examination.
b64-to-hex.shwill convert a base64 hash value from npm into hex, e.g.:$ echo x+sXyT4RLLEIb6bY5R+wZnt5pfk= | tools/b64-to-hex.sh c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9hex-to-b64.shwill convert a hex hash value into base64, e.g.:For convenience, any slashes inside the hex value will be removed, allowing you to copy-paste a path into the npm package cache and still get the base64 value:$ echo 867ac74e3864187b1d3d47d996a78ec5c8830777 | tools/hex-to-b64.sh hnrHTjhkGHsdPUfZlqeOxciDB3c=$ echo c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9 | tools/hex-to-b64.sh x+sXyT4RLLEIb6bY5R+wZnt5pfk= $ echo c7/eb/17c93e112cb1086fa6d8e51fb0667b79a5f9 | tools/hex-to-b64.sh x+sXyT4RLLEIb6bY5R+wZnt5pfk=b64-integrity.sh INTEGRITYwill run${INTEGRITY}sumand then convert its output into base64, e.g.:This is roughly equivalent to$ echo 123 | tools/b64-integrity.sh sha512 6i/la7jB+1rahJY7Qu1xt2SnSwktdXVRc63gby9KranADWwwLhhQNcvoX9/zFpi8qT6GYfDLzvUs8v9lhk/XQg==echo 123 | sha512sum, then converting the resulting hex digest to base64 viahex-to-b64.sh.