Self-contained Executable Programs with Deno Compile
Since Deno v1.6, the
deno compile command
has empowered developers to turn JavaScript and TypeScript programs into single,
standalone binaries that run on all major platforms—no dependencies, no
additional installs. This has big implications:
- Cross-platform compatibility: Distribute a single binary that works without a Deno runtime or dependencies.
- Bundled assets: Package everything your app needs inside the binary for easy portability.
- Streamlined deployment: Ship one binary to production, reducing complexities.
- Improved startup times: Faster launch times compared to typical server or runtime setups.
Since Deno 2, we’ve introduced even more improvements to deno compile,
like support for npm packages,
web workers,
cross-compilation,
smaller binary sizes, and
code signing with custom icons. These upgrades mean you can now
compile not only scripts but also complete applications like desktop games
directly to native binaries.
In this post, we’ll explore what makes deno compile unique, how it works, and
examples of different use cases that highlight its advantages over alternatives
in the ecosystem.
🚨️ Deno 2 is here. 🚨️
With backwards compatibility with Node/npm, built-in package management, all-in-one zero-config toolchain, and native TypeScript and web API support, writing JavaScript has never been simpler.
What is deno compile?
Deno offers
a zero-config toolchain for JavaScript and TypeScript,
so you don’t need to cobble together different tools before writing a single
line of code. One subcommand is deno compile, which lets you build a single
binary from your JavaScript or TypeScript code. And unlike Node’s
8-step compilation process,
deno compile is just one command.
This subcommand lets you skip install requirements and run binaries on systems without Deno installed, across platforms like Windows, macOS, and Linux. Deno’s compiled binaries are also optimized for size. If you’re coming from Node, this simplicity reduces friction when moving code between environments, especially when cross-compiling for different OS targets.
How deno compile works
Though it’s called “compile,” deno compile doesn’t compile JavaScript in the
traditional sense. Instead, it embeds your JavaScript and TypeScript into a
special Deno runtime binary, called denort (short for “Deno runtime”).
Here’s a high-level overview of the process when you execute deno compile:
- A slimmed-down version of the runtime,
denort, is downloaded. If you’re cross-compiling for a different operating system, thedenortfor that platform is downloaded. - Your script, along with any dependencies, is bundled to
an
eszipfile, a lossless format for serializing an ECMAScript module graph. - The bundle is injected into the
denortbinary using Sui.
By embedding the bundle into a section of the executable, the outputted binary can still be codesigned.
Examples
Basic self-contained binary
To start, let’s look at how easy it is to create a single executable from a TypeScript script.
// main.ts
import open from "jsr:@rdsq/open";
await open("https://www.youtube.com/watch?v=dQw4w9WgXcQ");Compiling it is as simple as:
deno compile -A -o runme main.tsThis outputs an executable binary (runme) that includes all required
dependencies. Now you can share this single file on any platform, without
requiring the end user to install Deno.
Note that you can pass
opt-in permission flags,
such as --allow-net, in the deno compile command. The permission flags will
then be preserved in the compiled binary, giving you an added layer of security
over how your binary can be used.
Cross-compiling for Windows
Say you want to share the app with a Windows user. Using
the --target flag,
you can cross-compile it for Windows:
deno compile --allow-all -o runme --target x86_64-pc-windows-msvc main.tsNow you’ve got runme.exe, a Windows-compatible binary. You can even add a
custom icon with
the --icon flag
for a more polished look:
deno compile --allow-all -o runme --target x86_64-pc-windows-msvc --icon icon.ico main.tsCode signing
Code signing ensures that your binary is verified and trustworthy, which is
critical for software distribution. Deno simplifies this, even on macOS, where
you can use codesign as with any other app.
Let’s confirm our binary’s integrity:
codesign --verify -vv ./runme
./runme: valid on disk
./runme: satisfies its Designated RequirementThe binary we compiled is properly code signed and ready for publishing.
Compiling NPM packages
Of course it’s possible to use NPM packages with deno compile. This approach
is ideal for performance-sensitive CI environments or when you need a single
portable version of a tool.
As an example, let’s use deno compile on npm itself:
deno compile -A npm:npmRunning the compiled npm binary is simple, and it even shows performance
boosts. In tests, Deno-compiled npm binaries ran ~1.9x faster than regular npm:
# hyperfine "./npm -v" "npm -v"
Benchmark 1: ./npm -v
Time (mean ± σ): 40.1 ms ± 2.0 ms [User: 37.7 ms, System: 5.3 ms]
Range (min … max): 38.9 ms … 51.8 ms 71 runs
Benchmark 2: npm -v
Time (mean ± σ): 75.2 ms ± 7.6 ms [User: 59.1 ms, System: 9.0 ms]
Range (min … max): 69.2 ms … 105.0 ms 40 runs
Summary
./npm -v ran
1.87 ± 0.21 times faster than npm -vThis approach works with other popular npm tools too, like prettier and
eslint, giving you faster, more portable versions.
Games and Desktop apps
deno compile also opens up the potential for bundling web-based games and apps
as native desktop executables. For example, you could take an
HTML/CSS/JavaScript game and turn it into a binary that’s easy to share and
launch on any desktop.
deno compile.Take a look at this Flappybird clone, which can be compiled into a desktop app using Deno:
deno compile --unstable-ffi --env -o flappybird -A main.jsBundling assets
Though deno compile doesn’t currently support bundling assets directly (yet!),
it’s possible
to convert .png or other asset files into base64-encoded .js files
and
import them into your project,
allowing them to be included in the final binary. This method, while a
workaround, enables developers to package games and other assets in a single
executable.
What’s next
We’re continually improving deno compile based on your feedback, with updates
on the way to streamline asset bundling, support more frameworks like Svelte,
reduce binary sizes, and improve startup times even further with caching.
🚨️ Want to learn more Deno? 🚨️
Check out our new Learn Deno tutorial series, where you’ll learn:
…and more, in short, bite-sized videos. New tutorials published every Tuesday and Thursday.

