Compile to a single-file executable
Distribute single-file apps with deno compile, covering cross-compilation, embedded assets, and selection boundaries
deno compile packs the entry module graph and the trimmed denort runtime into one self-contained executable. Target machines do not need Deno installed.
Basic usage
deno compile --output=server main.ts
./server
The output is a platform-specific binary. Runtime flags must be declared at compile time, including permissions:
deno compile --allow-net --allow-env=PORT --output=server main.ts
Cross-compilation
--target cross-compiles from any host platform. Five target triples are currently supported:
| Target | Platform |
|---|---|
x86_64-pc-windows-msvc | Windows x86_64 |
x86_64-apple-darwin | macOS x86_64 |
aarch64-apple-darwin | macOS ARM64 |
x86_64-unknown-linux-gnu | Linux x86_64 |
aarch64-unknown-linux-gnu | Linux ARM64 |
deno compile --target=aarch64-unknown-linux-gnu --output=server-linux-arm64 main.ts
The matching denort binary is downloaded into the DENO_DIR cache. Always boot a cross-compiled artifact once on the real target platform; "it compiled" is not a verification.
Embedding assets
Since Deno 2.1, --include embeds files or directories into the binary, readable through import.meta-relative paths:
deno compile --include=./data --include=worker.ts main.ts
const csv = await Deno.readTextFile(import.meta.dirname + "/data/names.csv");
--includecan be passed multiple times; only local files are supported, remote modules cannot be embedded.- Embedded
.js/.tsfiles become module-graph roots and are transpiled. For pre-built frontend bundles use--include-as-isto embed them verbatim. - The
compileblock indeno.jsondeclaresinclude/excludearrays, which merge with CLI flags. - The whole resolved
node_modulestree is embedded by default; the experimental--exclude-unused-npmflag embeds only reachable npm packages.
Boundary with Docker and Deploy
| Scenario | Preferred approach |
|---|---|
| Distributing CLI tools or single-file daemons | deno compile |
| Services needing system libraries, CAs, a shell, or multi-process setups | Docker and containers |
| HTTP services needing managed TLS, multi-region rollout, and autoscaling | Deno Deploy |
deno compile solves the distribution shape, not process management, rolling upgrades, or certificates. Long-running services still need systemd, an orchestrator, or a hosted platform.
Known limitations
- Only string-literal dynamic imports are included statically; computed specifiers must be pulled in with
--include. - Worker code is not part of the artifact by default; bring it in via
--includeor a staticimport "./worker.ts". - Native plugins (FFI,
.nodeaddons) rely on self-extracting mode, which slows down first runs and uses extra disk; verify per target platform. - The binary is bound to a Deno version; runtime upgrades mean recompiling and redistributing.
Official reference: deno compile.