Skip to main content

Overview

Deno is designed to be compatible with modern web standards. It implements many of the same APIs available in web browsers, allowing code to run in both Deno and browser environments.
Deno aims for maximum compatibility with web standards, implementing APIs from WHATWG, W3C, and other standards bodies.

Web APIs Available in Deno

From the ext/web extension source code, Deno implements these web APIs:

Core APIs

Event System

Event, EventTarget, CustomEvent, ErrorEvent

Text Encoding

TextEncoder, TextDecoder, TextEncoderStream, TextDecoderStream

Streams

ReadableStream, WritableStream, TransformStream

File APIs

File, Blob, FileReader

Complete API List

Based on ext/web/README.md:
// Events
Event
EventTarget
CustomEvent
ErrorEvent
CloseEvent
MessageEvent
ProgressEvent
PromiseRejectionEvent

// Encoding
TextEncoder
TextDecoder
TextEncoderStream
TextDecoderStream

// Binary Data
Blob
File
FileReader

// Streams
ReadableStream
ReadableStreamDefaultReader
ReadableStreamBYOBReader
ReadableByteStreamController
ReadableStreamDefaultController
WritableStream
WritableStreamDefaultWriter
WritableStreamDefaultController
TransformStream
TransformStreamDefaultController
ByteLength QueuingStrategy
CountQueuingStrategy

// Compression
CompressionStream
DecompressionStream

// Messaging
MessageChannel
MessagePort

// Utilities
AbortController
AbortSignal
DOMException
ImageData
Performance
PerformanceEntry
PerformanceMark
PerformanceMeasure

// Global Functions
atob
btoa
setTimeout
setInterval
clearTimeout
clearInterval
structuredClone
reportError
performance

Fetch API

Deno implements the complete Fetch API:
// Basic fetch
const response = await fetch("https://deno.land");
const text = await response.text();

// With options
const response = await fetch("https://api.example.com/data", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer token",
  },
  body: JSON.stringify({ name: "Deno" }),
});

const data = await response.json();

Request and Response

// Create a Request
const request = new Request("https://api.example.com", {
  method: "POST",
  headers: new Headers({
    "Content-Type": "application/json",
  }),
  body: JSON.stringify({ data: "value" }),
});

// Create a Response
const response = new Response("Hello World", {
  status: 200,
  headers: {
    "Content-Type": "text/plain",
  },
});

Headers API

const headers = new Headers();
headers.set("Content-Type", "application/json");
headers.append("X-Custom-Header", "value");

for (const [key, value] of headers) {
  console.log(`${key}: ${value}`);
}

URL APIs

URL Construction

const url = new URL("https://deno.land/std/http/server.ts");

console.log(url.protocol);  // "https:"
console.log(url.hostname);  // "deno.land"
console.log(url.pathname);  // "/std/http/server.ts"

// Modify URL
url.searchParams.set("version", "0.220.0");
console.log(url.href);  // "https://deno.land/std/http/server.ts?version=0.220.0"

URLSearchParams

const params = new URLSearchParams({
  name: "Deno",
  version: "2.0",
});

params.append("feature", "fast");
params.append("feature", "secure");

console.log(params.toString());
// "name=Deno&version=2.0&feature=fast&feature=secure"

for (const [key, value] of params) {
  console.log(`${key}: ${value}`);
}

URLPattern

const pattern = new URLPattern({ pathname: "/users/:id" });

const match = pattern.exec("https://example.com/users/123");
console.log(match?.pathname.groups.id);  // "123"

Streams API

Full implementation of WHATWG Streams:

ReadableStream

const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("chunk 1");
    controller.enqueue("chunk 2");
    controller.close();
  },
});

const reader = stream.getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(value);
}

WritableStream

const stream = new WritableStream({
  write(chunk) {
    console.log("Writing:", chunk);
  },
  close() {
    console.log("Stream closed");
  },
});

const writer = stream.getWriter();
await writer.write("Hello");
await writer.write("World");
await writer.close();

TransformStream

const transformStream = new TransformStream({
  transform(chunk, controller) {
    controller.enqueue(chunk.toString().toUpperCase());
  },
});

const readable = new ReadableStream({
  start(controller) {
    controller.enqueue("hello");
    controller.close();
  },
});

const transformed = readable.pipeThrough(transformStream);

for await (const chunk of transformed) {
  console.log(chunk);  // "HELLO"
}

Web Crypto API

Complete implementation of the Web Crypto standard:
// Generate random values
const array = new Uint8Array(32);
crypto.getRandomValues(array);

// Generate UUID
const uuid = crypto.randomUUID();

// Hash data
const data = new TextEncoder().encode("Hello, World!");
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("");

// Generate key pair
const { publicKey, privateKey } = await crypto.subtle.generateKey(
  {
    name: "RSA-PSS",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  },
  true,
  ["sign", "verify"]
);

Console API

Browser-compatible console:
// Logging
console.log("Message");
console.info("Info");
console.warn("Warning");
console.error("Error");
console.debug("Debug");

// Groups
console.group("Group");
console.log("Inside group");
console.groupEnd();

// Tables
console.table([{ name: "Deno", type: "runtime" }]);

// Timing
console.time("operation");
// ... do work
console.timeEnd("operation");

// Assertions
console.assert(1 === 1, "This won't print");
console.assert(1 === 2, "This will print");

Timers

Web-compatible timer functions:
// setTimeout
const timeout = setTimeout(() => {
  console.log("Delayed execution");
}, 1000);

clearTimeout(timeout);

// setInterval
const interval = setInterval(() => {
  console.log("Repeated execution");
}, 1000);

clearInterval(interval);

// Promises-based alternatives
await new Promise(resolve => setTimeout(resolve, 1000));

AbortController and AbortSignal

Standard abort functionality:
const controller = new AbortController();
const signal = controller.signal;

// Use with fetch
const fetchPromise = fetch("https://example.com", { signal });

// Abort after timeout
setTimeout(() => controller.abort(), 5000);

try {
  const response = await fetchPromise;
} catch (err) {
  if (err.name === "AbortError") {
    console.log("Fetch aborted");
  }
}

// Listen for abort
signal.addEventListener("abort", () => {
  console.log("Operation aborted");
});

Performance API

// High-resolution timestamps
const start = performance.now();
// ... do work
const end = performance.now();
console.log(`Operation took ${end - start}ms`);

// Performance marks
performance.mark("start-task");
// ... do work
performance.mark("end-task");
performance.measure("task-duration", "start-task", "end-task");

const measures = performance.getEntriesByType("measure");
console.log(measures[0].duration);

Encoding API

TextEncoder / TextDecoder

// Encode text to bytes
const encoder = new TextEncoder();
const bytes = encoder.encode("Hello, World!");

// Decode bytes to text
const decoder = new TextDecoder();
const text = decoder.decode(bytes);

// Streaming encoding
const stream = new ReadableStream({
  start(controller) {
    controller.enqueue("Hello");
    controller.enqueue(" World");
    controller.close();
  },
}).pipeThrough(new TextEncoderStream());

Base64

// Encode to base64
const encoded = btoa("Hello, World!");

// Decode from base64
const decoded = atob(encoded);

Blob and File APIs

// Create a Blob
const blob = new Blob(
  ["Hello, World!"],
  { type: "text/plain" }
);

console.log(blob.size);  // 13
console.log(blob.type);  // "text/plain"

// Read blob content
const text = await blob.text();
const arrayBuffer = await blob.arrayBuffer();

// Slice blob
const slice = blob.slice(0, 5, "text/plain");

// Create a File
const file = new File(
  ["content"],
  "example.txt",
  { type: "text/plain", lastModified: Date.now() }
);

console.log(file.name);  // "example.txt"

MessageChannel and MessagePort

const channel = new MessageChannel();
const { port1, port2 } = channel;

port2.onmessage = (event) => {
  console.log("Received:", event.data);
};

port1.postMessage("Hello from port1");

Structured Clone

const original = {
  name: "Deno",
  date: new Date(),
  map: new Map([["key", "value"]]),
};

const cloned = structuredClone(original);

// Deep clone with circular references support
const obj: any = { name: "test" };
obj.self = obj;
const clonedCircular = structuredClone(obj);

Web Standards Compliance

Deno passes the majority of Web Platform Tests (WPT):
# Run Web Platform Tests
cd tests/wpt/runner
deno run -A runner.ts
Deno regularly runs the official Web Platform Test suite to ensure compatibility with browser implementations.

Differences from Browsers

While Deno implements web standards, some differences exist:
Deno doesn’t include document, window.document, or DOM manipulation APIs since it’s a server runtime.
The global object is globalThis, not window (though window is aliased to globalThis for compatibility).
Deno adds its own Deno namespace with additional APIs not available in browsers.
Deno uses ES modules exclusively, while browsers support both ES modules and classic scripts.

Cross-Platform Code

Write code that runs in both Deno and browsers:
// Check environment
const isDeno = typeof Deno !== "undefined";
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";

// Use web-standard APIs
const response = await fetch("https://api.example.com/data");
const data = await response.json();

// This works in both environments!
// Works in Deno and browsers
export async function fetchData(url: string) {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  return await response.json();
}

export function encodeData(text: string): Uint8Array {
  return new TextEncoder().encode(text);
}

Browser Compatibility

Deno’s web-standard approach means: ✅ Code using web APIs works in browsers ✅ No need for polyfills for standard features ✅ Familiar APIs for web developers ✅ Easy to share code between frontend and backend

Learn More

Explore the Deno Runtime to understand how these web APIs are implemented on top of V8, Rust, and Tokio.

Build docs developers (and LLMs) love