This fork has now significantly diverged from upstream as the original author didn't have time to review and merge our improvements. We've since done some refactoring (including treewide code formatting) which will make it difficult to merge the changes upstream in the near future, so the fork will most likely continue evolving independently from upstream.
Some notable improvements over the original:
- unplugged packages (ones which require a build step) are normal derivations instead of FODs so manually maintaining their hashes is not required
yarn patchjust works, without having to manually fix up paths to patches in package.json files form using~(meaning root of the project) to relative
The original README below might contain some info which is not applicable to this fork. Eventually we'll replace it with up to date info.
Yet another way of packaging Node applications with Nix. Unlike alternatives, this plugin is built for performance (both speed and disk usage) and aims to be unique with the following goals:
- NPM dependencies should be stored in the /nix/store individually rather than in a huge "node_modules" derivation. Zip files should be used where possible to work well with Yarn PNP
- Rebuilding when just changing source code should be fast as dependencies shouldn't be fetched
- Adding a new dependency should just fetch that dependency rather than fetching or linking all node_modules again
- Build native modules (e.g canvas) once, and once they are built they shouldn't be built again across packages
- Unplugged/native modules should have their outputs hashed to try and enforce reproducibility
- When using workspaces, adding a dependency in another package (modifying the yarn.lock file) in the workspace shouldn't cause a different package to have to be rebuilt
- devDependencies shouldn't be included as references in the final runtime derivation, only dependencies
Requires a Yarn version > 3 project using PnP linking (the default). Zero installs are not required, so it's recommended to just use the global cache when developing your project rather than storing dependencies in your repo.
-
Install Yarn plugin in your project:
yarn plugin import https://github.com/madjam002/yarnpnp2nix/raw/master/plugin/dist/plugin-yarnpnp2nix.js -
Run
yarnto make sure all packages are installed and to automatically generate ayarn-manifest.nixfor your project. -
Create a
flake.nixif you haven't already for your project, add this repo (yarnpnp2nix) as an input (e.gyarnpnp2nix.url = github:madjam002/yarnpnp2nix;) -
See test/flake.nix for an example on how to create Nix derivations for Yarn packages using
mkYarnPackagesFromManifest.
Setting a build command for a package:
mkYarnPackagesFromManifest {
yarnManifest = import ./workspace/yarn-manifest.nix;
packageOverrides = {
"my-package@workspace:packages/my-package".build = ''
// Any custom build logic here
'';
};
};Fixing a hash mismatch:
mkYarnPackagesFromManifest {
yarnManifest = import ./workspace/yarn-manifest.nix;
packageOverrides = {
"my-package@workspace:packages/my-package".outputHash = "sha512-4pNZfI6GbsEsBySIs+gK98AGZhWf9QZ3SLytsWIzLnCeJYt2ma6qVK5Gk4TSHsUOmSjqUX8seBCKBBL7f1pvTQ==";
};
};Known caveats:
-
Initial build can be a bit slow as each dependency is a separate derivation and needs to be fetched from the package registry. Still, a sample project with a couple of thousand dependencies (!!) only takes a couple of minutes to build all of the dependency derivations. Make sure you have enough parallelism in your
nix build(either using the-jargument or setting your Nix config appropriately) -
Patched packages with localy stored patches need to have their revision strings updated to use relative paths instead of the default
~/prefixFor example, to fix a revision of a package stored in
packages/my-package(relative to the workspace root), update the revision as such:
- "next": "patch:next@npm%3A13.2.1#~/.yarn/patches/next-npm-13.2.1-585715321e.patch",
+ "next": "patch:next@npm%3A13.2.1#../../.yarn/patches/next-npm-13.2.1-585715321e.patch",Possible future improvements:
- When adding a Yarn package, copy it straight into the nix store rather than a Yarn cache in the users home directory
- ...and run postinstall/install builds from within Nix by defaulting Yarn to --ignore-scripts
Licensed under the MIT License.
View the full license here.