Open-Source Wikis

/

Deno

/

Extensions

denoland/deno

Extensions

Active contributors: Bartek Iwańczuk, Divy Srivastava, Yoshiya Hinosawa, Marvin Hagemeister

The ext/ directory contains 31 self-contained crates, one per "extension". An extension bundles a slice of Rust ops with the JS that exposes them to user code: Deno.openSync lives in ext/fs, fetch() lives in ext/fetch, WebSocket lives in ext/websocket, and so on.

Each extension is registered with the runtime by runtime/lib.rs and instantiated during worker construction in runtime/worker.rs and runtime/web_worker.rs.

What an extension actually is

graph LR
    subgraph Ext["ext/<name>/ — one extension crate"]
        Cargo["Cargo.toml"]
        LibRs["lib.rs<br/>deno_core::extension!()"]
        Ops["*.rs<br/>#[op2] fn op_*"]
        Js["*.js<br/>user-visible API"]
    end
    LibRs -->|registers| OpReg["ops: [op_a, op_b, …]"]
    LibRs -->|registers| JsReg["esm: [01_foo.js, 02_bar.js]"]
    Ops -->|callable from| Js
    Js -->|exposed as| Globals["globalThis.fetch / Deno.* / etc"]
    Runtime["runtime/lib.rs"] --> LibRs

Conventions:

  • lib.rs calls the deno_core::extension!(name = ..., ops = [...], esm_entry_point = "...", esm = [...]) macro.
  • Op functions use #[op2] from deno_core and live in either lib.rs or sibling *.rs files.
  • JS files are numbered (00_*, 01_*, …) to control snapshot load order.
  • A README.md per extension typically points to the user-visible API doc page.

The full list

Every ext/<name>/ is a standalone Cargo crate. Counts below are at the snapshot date.

Web platform APIs

Crate Description Rust files JS files
ext/web Collection of Web APIs (URL, Event, AbortController, streams, MessagePort, base64, timers, performance, …) 13 24
ext/fetch fetch, Request, Response, Headers, FormData 5 8
ext/websocket WebSocket, WebSocketStream 2 2
ext/webstorage localStorage / sessionStorage 1 1
ext/webidl WebIDL type conversions used by other extensions 1 1
ext/webgpu WebGPU bindings (largest in terms of Rust at 23 files) 23 3
ext/url Deprecated; use deno_web 1 0
ext/console Deprecated; use deno_web 1 0
ext/broadcast_channel Deprecated; use deno_web 1 0
ext/crypto WebCrypto (SubtleCrypto, crypto.randomUUID, …) 11 1

Filesystem, network, OS

Crate Description Rust files JS files
ext/fs Deno.open, Deno.readFile, watch APIs 4 1
ext/net TCP/UDP/Unix sockets (Deno.listen, Deno.connect) 11 3
ext/http HTTP server primitives (powers Deno.serve) 10 1
ext/tls TLS for net and http 3 0
ext/io IO primitives (stdin/stdout, resource tables) 6 1
ext/os OS APIs (hostname, env-aware paths, Deno.osRelease) 2 2
ext/process Subprocess APIs (Deno.Command, child_process core) 2 1
ext/signals Signal handling (Deno.addSignalListener) 2 0

Node.js compatibility

Crate Description Rust files JS files
ext/node The big one: node:* polyfills (in polyfills/) plus core ops 2 (+ many in subdirs) many in polyfills/
ext/node_crypto Splits Node's crypto layer out of ext/node 10 0
ext/node_sqlite node:sqlite polyfill 8 0

Deno-specific

Crate Description Rust files JS files
ext/kv Deno.openKv() — built-in KV store 6 0
ext/cron Deno.cron() scheduled jobs 5 0
ext/cache Web Cache API (caches.open) 4 1
ext/bundle The bundle subcommand's runtime API hooks 0 0
ext/rt_helper Helpers for denort (the binary used by deno compile) 1 0
ext/telemetry OpenTelemetry exporter for spans/metrics/logs 2 0

Native code interop

Crate Description Rust files JS files
ext/ffi Deno.dlopen (call into shared libraries) 9 1
ext/napi Node-API native addons 8 0

Misc

Crate Description Rust files JS files
ext/image Image decoding / ImageData / ImageBitmap 3 1

Detail pages

Three of the largest extensions have their own deeper page:

  • ext/web — the kitchen-sink web platform crate; touches almost every JS file you'll find under runtime/js/ and is the foundation for every other web API extension
  • ext/node — the Node.js compatibility surface; thousands of lines of polyfills, the core of how npm: packages run on Deno
  • ext/fs — the filesystem extension; canonical example of the op-pattern + permission integration

For the rest of the extensions, the README in each ext/<name>/ plus the lib.rs are the entry points.

How to add a new op

  1. Pick the right extension. New web APIs go in ext/web. New filesystem APIs in ext/fs. Node polyfills in ext/node/polyfills/<module>.ts.
  2. Add an #[op2] Rust function in a sibling *.rs file:
    #[op2(async)]
    pub async fn op_my_new_thing(
        state: Rc<RefCell<OpState>>,
        #[string] arg: String,
    ) -> Result<i32, AnyError> { ... }
  3. Register it with the extension macro in lib.rs:
    deno_core::extension!(
        deno_my_ext,
        ops = [op_my_new_thing, /* …existing ops… */],
        esm = ["00_my_ext.js"],
    
    );
  4. Use it from JS:
    const { op_my_new_thing } = core.ops;
    export async function myNewThing(arg) {
      return await op_my_new_thing(arg);
    }
  5. Add the user-facing JS API to a numbered file, then expose it via the bootstrap (runtime/js/) if needed.
  6. If the op does anything privileged, add a state.borrow_mut::<PermissionsContainer>().check_*(...) call.
  7. Add a unit test under tests/unit/.

How to add a new extension

Rare, but if you must:

  1. cargo new --lib ext/my_ext
  2. Add the new directory to the workspace members list in the top-level Cargo.toml.
  3. Pattern your lib.rs after a small existing extension (e.g., ext/cache or ext/cron).
  4. Add pub use deno_my_ext; to runtime/lib.rs.
  5. Register the extension in runtime/worker.rs and runtime/web_worker.rs by adding deno_my_ext::deno_my_ext::init_ops_and_esm(...) to the extension list.
  6. Test it with a unit test or spec test.

See Patterns and conventions for the op signature conventions.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Extensions – Deno wiki | Factory