libdeno
Embed the Deno runtime in Rust with direct
npm:specifier support.
libdeno is a Rust crate that embeds a full Deno runtime (V8 + the official module graph pipeline) inside your program. Your JS/TS code can import npm packages, remote modules, jsr: and node: builtins directly, all handled by the official Deno resolver stack — the same behavior as deno run, but running inside your process.
中文版文档:README.zh-CN.md
Features
- Official module graph pipeline:
npm:,jsr:, remotehttps://,node:, local files, JSON, WASM, import maps (fromdeno.json), and TypeScript transpilation are all handled bydeno_graph+deno_resolver. - npm integration: automatically discovers and uses an existing
node_modules(BYONM); installs on demand otherwise (managed mode). Supports CJS packages and.nodenative addons. npm lifecycle scripts do not run by default (matching deno CLI 2.x). child_process.forksupport: the npm resolution snapshot propagates to child processes.- Web Workers:
new Worker(...)nested workers reuse the same module loader and snapshot. - Permission model: CLI-style
--allow-*capability strings; an empty list allows everything by default. - Unstable APIs enabled out of the box:
Deno.openKv, cron, FFI, WebGPU, etc. (an "everything enabled" stance, likedeno run --unstable). - Prebuilt V8 snapshot: runtime extensions are compiled into a snapshot at build time for faster cold start.
Quick Start
use ;
let options = LibdenoOptions ;
let exit_code = run.unwrap;
run accepts three kinds of entry:
- A file:
run("app.ts", ...) - A directory:
run("./my-app", ...)(uses itspackage.jsonmain, defaultindex.js) - A
package.jsonitself:run("./my-app/package.json", ...)
Run the demo
# Build (takes a few minutes the first time: V8 snapshot + full dependency tree)
# Run an app that mixes an npm package, a node builtin, a local module, and a JSON import
# npm package (chalk) works
# node builtin (node:path): a/b/c
# local module: 1 + 2 = 3
# json import: name=demo-app deps=1
# TypeScript entry
# ts entry + chalk: ok
# A directory entry
&&
API
| Item | Description |
|---|---|
run(entry, &options) -> Result<i32, LibdenoError> |
Runs the entry to completion and returns the exit code the script requested. Each call builds an independent current-thread runtime and worker, so multiple invocations are fully isolated. |
run_in_subprocess(entry, &options) -> Result<i32, LibdenoError> |
Runs the entry in a child process. Deno.exit(n) then terminates only the child; the host stays alive and observes n. The host must call maybe_handle_child_mode() at the start of main(). |
maybe_handle_child_mode() -> bool |
Services run_in_subprocess child requests. Returns false on a normal host launch; in child mode it executes the script and exits with its code. |
LibdenoOptions.permissions: Vec<String> |
--allow-* capability strings. An empty list allows everything; passing any entry restricts the runtime to the declared capabilities. |
LibdenoOptions.args: Vec<String> |
Arguments exposed to the script via process.argv (after argv[0]). |
LibdenoOptions.cwd: Option<PathBuf> |
Working directory that relative paths (entry, permissions, node_modules discovery) resolve against. Defaults to the process current directory. |
LibdenoError |
Enum: Entry (entry resolution failed), Permission (invalid permission flag), Runtime, Core, Js (script exception), Io. |
Supported permission flags: --allow-read[=paths] --allow-write[=paths] --allow-env[=names] --allow-net[=hosts] --allow-run[=names] --allow-ffi[=paths] --allow-sys[=names], plus -A / --allow-all.
Full API documentation: docs/api.md.
Build
- Rust edition 2021. Dependencies match the official Deno stack:
deno_runtime 0.265,deno_core 0.410,deno_resolver 0.88,deno_graph 0.110. - The build script (
build.rs) generates the V8 snapshot and pre-transpiles residual lazy-load sources;DENO_SNAPSHOT_MINIFY_SOURCEStriggers source minification. - The first build is slow (V8 snapshot + full dependency tree). Release debug symbols are disabled in
Cargo.toml. .nodenative addon symbol export: the example host uses.cargo/config.toml(dev-only) to exportnapi_*. Real embedders should calldeno_napi::print_linker_flags("<host-binary-name>")in their ownbuild.rs.
Documentation
License
MIT