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" ,
},
});
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 ();
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" );
});
// 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.
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.