`buildDenoPackage` allows you to package [Deno](https://deno.com/) projects in Nixpkgs without the use of an auto-generated dependencies file (as used in [node2nix](#javascript-node2nix)).
It works by utilizing Deno's cache functionality -- creating a reproducible cache that contains the dependencies of a project, and pointing Deno to it.
For every `buildDenoPackage`, first, a [fixed output derivation](https://nix.dev/manual/nix/2.18/language/advanced-attributes.html#adv-attr-outputHash) is
created with all the dependencies mentioned in the `deno.lock`.
This works as follows:
1. They are installed using `deno install`.
1. All non-reproducible data is pruned.
1. The directories `.deno`, `node_modules` and `vendor` are copied to `$out`.
1. The output of the FOD is checked against the `denoDepsHash`.
1. The output is copied into the build of `buildDenoPackage`, which is not an FOD.
1. The dependencies are installed again using `deno install`, this time from the local cache only.
The `buildDenoDeps` derivation is in `passthru`, so it can be accessed from a `buildDenoPackage` derivation with `.denoDeps`
Related options:
*`denoDepsHash`* (String)
: The output hash of the `buildDenoDeps` fixed output derivation.
*`denoInstallFlags`* (Array of strings; optional)
: The Flags passed to `deno install`.
: _Default:_ `[ "--allow-scripts" "--frozen" "--cached-only" ]` for `buildDenoPackage`
: _Default:_ `[ "--allow-scripts" "--frozen" ]` for `buildDenoDeps` (`"--cached-only"` is filtered out)
::: {.tip}
If you receive errors like these:
```
error: The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.
```
or
```
error: Import '<url>' failed.
0: error sending request for url (<url>): client error (Connect): dns error: failed to lookup address information: Temporary failure in name resolution: failed to lookup address information:Temporary failure in name resolution
1: client error (Connect)
2: dns error: failed to lookup address information: Temporary failure in name resolution
3: failed to lookup address information: Temporary failure in name resolution
at file:///build/source/src/lib/helpers/verifyRequest.ts:2:21
build for <your-package> failed in buildPhase with exit code 1
```
or
```
error: Specifier not found in cache: "<url>", --cached-only is specified.
ERROR: deno failed to install dependencies
```
This can happen due to the `deno install` command deducing different packages than what the actual package needs.
To fix this, add the entrypoint to the install flags:
Hardcoding a token into your NixOS configuration or some other nix build, will as a consequence write that token into `/nix/store`, which is considered world readable.
:::
::: {.note}
Neither approach is ideal. For `buildNpmPackage`, there exists a third
option called `sourceOverrides`, which allows the user to inject Nix packages into
the output `node_modules` folder.
Since a Nix build implicitly uses the SSH keys of the machine,
this offers a third option to access private packages.
But this creates the requirement, that the imported package is packaged with nix first,
and that the source code can be retrieved with SSH.
This is possible for Deno, too, albeit it not
completely analogous to `buildNpmPackage`'s solution.
However, it has not been implemented yet.
:::
#### Compile to binary {#javascript-buildDenoPackage-compile-to-binary}
It's possible to compile a Deno project to a single binary using `deno compile`.
The binary will be named like the `.name` property in `deno.json`, if available,
or the `name` attribute of the derivation.
:::{.caution}
When using packages with a `npm:` specifier, the resulting binary will not be reproducible.
See [this issue](https://github.com/denoland/deno/issues/29619) for more information.
:::
Related options:
*`hostPlatform`* (String; optional)
: The [host platform](#ssec-cross-platform-parameters) the binary is built for.
: _Default:_ `builtins.currentSystem`.
: _Supported values:_
-`"x86_64-darwin"`
-`"aarch64-darwin"`
-`"x86_64-linux"`
-`"aarch64-linux"`
*`denoCompileFlags`* (Array of string; optional)
: Flags passed to `deno compile [denoTaskFlags] ${binaryEntrypointPath} [extraCompileFlags]`.
*`extraCompileFlags`* (Array of string; optional)
: Flags passed to `deno compile [denoTaskFlags] ${binaryEntrypointPath} [extraCompileFlags]`.
*`binaryEntrypointPath`* (String or null; optional)
: If not `null`, a binary is created using the specified path as the entry point.
The binary is copied to `$out/bin` in the `installPhase`.
: _Default:_ `null`
: It's prefixed by `denoWorkspacePath`.
*`denortPackage`* (Derivation; optional)
: The package used as the Deno runtime, which is bundled with the JavaScript code to create the binary.
: _Default:_ `pkgs.denort`
: Don't use `pkgs.deno` for this, since that is the full Deno CLI, with all the development tooling.
: If you're cross compiling, this needs to be the `denort` of the `hostPlatform`.
::: {.note}
The binary will be dynamically linked and not executable on NixOS without [nix-ld](https://github.com/nix-community/nix-ld)
or [other methods](https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos).
```nix
# configuration.nix
{
config,
lib,
pkgs,
...
}:
{
programs.nix-ld.enable=true;
programs.nix-ld.libraries=withpkgs;[
glibc
gcc-unwrapped
];
}
```
:::
:::{.example}
##### example binary build {#javascript-buildDenoPackage-compile-to-binary-example}
-`ddclient` was updated from 3.11.2 to 4.0.0 [Release notes](https://github.com/ddclient/ddclient/releases/tag/v4.0.0)
-`buildDenoPackage` was added [see docs](https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/javascript.section.md#avascript-buildDenoPackage) for more details