Nix builders for Deno projects.
Still a WIP, but here's what works / is done:
-
denoPlatform.mkDenoDir
: cache Deno dependencies in a pure Nix expression, no external scripts needed. - scripts without dependencies.
- https://deno.land, https://esm.sh style dependencies.
- NPM dependencies. I use this repo to build my Lume website, which has lots of NPM dependencies, please open an issue if you run into NPM problems!
-
denoPlatform.mkDenoDerivation
: a basicstdenv.mkDerivation
wrapper that handles dependencies for you. - helper for
deno compile
. - helper for
deno bundle
. Newer alternatives likedeno_emit
are still a TODO. - more helpful docs, right now, I'd suggest having a look at
./ci.nix
for basic usage info. - a release.
This section will guide you through setting up and building a simple Deno application using the nix-deno overlay.
The examples assume the following structure:
Deno Project
│
├── main.ts # The main TypeScript file for your Deno application
├── deno.json # The Deno project configuration file
├── deno.lock # A lock file for managing dependencies
└── flake.nix # The flake under discussion below
Here's a complete flake.nix example for building an executable for a typical Deno project:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nix-deno.url = "github:nekowinston/nix-deno";
outputs = { self, nixpkgs, flake-utils, ... } @ inputs:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
overlays = [ inputs.nix-deno.overlays.default ];
};
in {
packages.example-executable = pkgs.denoPlatform.mkDenoBinary {
name = "example-executable";
version = "0.1.2";
src = ./.;
buildInputs = [ ]; # other dependencies
permissions.allow.all = true;
};
defaultPackage = self.packages.${system}.example-executable;
});
}
For projects that generate artifacts (in this example a deno app which generates a folder of pdf files), you might have a deno.json like:
{
"tasks": {
"buildPdfs": "deno run --allow-run --allow-net --allow-read=/ --allow-write=. main.ts"
}
}
In which case your flake.nix might look like this:
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nix-deno.url = "github:nekowinston/nix-deno";
outputs = { self, nixpkgs, flake-utils, ... } @ inputs:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
overlays = [ inputs.nix-deno.overlays.default ];
};
in {
packages.pdfGen = pkgs.denoPlatform.mkDenoDerivation {
name = "pdfGen";
version = "0.1.2";
src = ./.;
buildInputs = [ pkgs.xdg-utils ]; # assuming reliance on xdg-utils
buildPhase = ''
mkdir -p $out
deno task buildPdfs
'';
installPhase = ''
cp ./*.pdf $out
'';
};
defaultPackage = self.packages.${system}.pdfGen;
});
}
Build the Project: Execute nix build
in your project directory. This will build the project based on the flake.nix configuration.
If you do not override the buildPhase (like we have not, in the example-executable
), after building you can run ./result/bin/example-executable
.
The example with the pdfGen
overrides the buildPhase
and installPhase
, so you will only see whatever is copied into the $out
folder manually (some pdfs in this case).
I love Deno. 🥰