libdeno 0.1.0

Embed the Deno runtime in Rust with direct npm: specifier support
docs.rs failed to build libdeno-0.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: libdeno-0.1.1

libdeno

crates.io docs.rs

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:, remote https://, node:, local files, JSON, WASM, import maps (from deno.json), and TypeScript transpilation are all handled by deno_graph + deno_resolver.
  • npm integration: automatically discovers and uses an existing node_modules (BYONM); installs on demand otherwise (managed mode). Supports CJS packages and .node native addons. npm lifecycle scripts do not run by default (matching deno CLI 2.x).
  • child_process.fork support: 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, like deno run --unstable).
  • Prebuilt V8 snapshot: runtime extensions are compiled into a snapshot at build time for faster cold start.

Quick Start

use libdeno::{LibdenoOptions, run};

let options = LibdenoOptions {
  permissions: vec!["--allow-read=.".into(), "--allow-net=example.com".into()],
  args: vec![],
  cwd: None,
};
let exit_code = run("app.js", &options).unwrap();

run accepts three kinds of entry:

  • A file: run("app.ts", ...)
  • A directory: run("./my-app", ...) (uses its package.json main, default index.js)
  • A package.json itself: run("./my-app/package.json", ...)

Run the demo

# Build (takes a few minutes the first time: V8 snapshot + full dependency tree)
cargo build --example demo

# Run an app that mixes an npm package, a node builtin, a local module, and a JSON import
./target/debug/examples/demo examples/demo-app/index.js
# 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
./target/debug/examples/demo examples/demo-app/tschalk_test.ts
# ts entry + chalk: ok

# A directory entry
cd examples/demo-app && ../../target/debug/examples/demo .

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_SOURCES triggers source minification.
  • The first build is slow (V8 snapshot + full dependency tree). Release debug symbols are disabled in Cargo.toml.
  • .node native addon symbol export: the example host uses .cargo/config.toml (dev-only) to export napi_*. Real embedders should call deno_napi::print_linker_flags("<host-binary-name>") in their own build.rs.

Documentation


License

MIT