Vercel Edge Runtime

repository·main·Indexed 21 days ago

https://github.com/vercel/edge-runtime

A toolkit for framework authors to implement edge computing based on Web standards and WinterCG. It provides a V8-based runtime environment with a subset of Web Standard APIs (Network, Encoding, Web Stream, Web Crypto) and V8 primitives. Includes a CLI for REPL, evaluation, and local HTTP server modes, as well as specialized packages like @edge-runtime/cookies for HTTP cookie manipulation.

Tokens
28.4K
Snippets
112
Records
140
Agent score
75%

What's inside edge-runtime

  1. What is Edge Runtime

    main

    The Edge Runtime is a toolkit designed for framework authors to adopt edge computing and provide open-source tooling built on Web standards. It is intended to be integrated into frameworks (such as Next.js) rather than being used directly in application code.

    Key characteristics:

    • Web Standards Compliance: Designed to be compliant with standards developed by WinterCG.
    • API Subset: It provides a subset of Node.js APIs to ensure compatibility and interoperability across multiple web environments.
    • Runtime Engine: In production, it uses the JavaScript V8 engine and does not use Node.js. Consequently, there is no access to Node.js APIs in a production environment.
    • Local Development: During local development and testing, the Edge Runtime polyfills Web APIs and ensures compatibility with the Node.js layer.
  2. Understand Edge Runtime restrictions and unsupported APIs

    main

    The Edge Runtime has specific limitations regarding Node.js compatibility and JavaScript execution:

    Node.js Compatibility

    • Native Node.js APIs are not supported: You cannot perform operations like reading or writing to the filesystem using Node.js built-ins.
    • Module System: You cannot use require directly. You must use ES Modules.
    • node_modules: You can use packages from node_modules provided they implement ES Modules and do not rely on native Node.js APIs.

    Disabled JavaScript Features

    The following features are disabled and will not function:

    • eval: Evaluating JavaScript code from a string.
    • new Function(evalString): Creating a new function from a string argument.
  3. How @edge-runtime/ponyfill works across environments

    main

    The @edge-runtime/ponyfill package acts as a compatibility layer for Edge Runtime APIs. It follows a conditional loading strategy:

    1. Edge Runtime: No polyfills are loaded; the package uses the native implementations available in the environment.
    2. Node.js: The package loads polyfills from @edge-runtime/primitives to emulate the Edge Runtime behavior.

    This allows developers to write code once and run it across different runtimes without worrying about missing global APIs.

  4. Understand Edge Runtime polyfills and Node.js compatibility

    main

    The Edge Runtime is built on top of Web APIs. To ensure backward compatibility with older Node.js environments, the runtime provides polyfills for Web APIs that are missing in certain Node.js versions.

    Key compatibility details:

    • The minimum supported Node.js version is v14.6.0, which maps to ES2019.
    • The runtime polyfills specific Web APIs to ensure they are available even when the underlying Node.js version does not natively support them.
  5. Use @edge-runtime/ponyfill for cross-environment compatibility

    main

    To ensure your code runs identically across both Edge Runtime and Node.js, do not access Edge Runtime APIs from the global scope. Instead, import them directly from @edge-runtime/ponyfill.

    When running in the Edge Runtime, the package uses native implementations. When running in Node.js, it loads polyfills from @edge-runtime/primitives.

    import { crypto, TextEncoder } from '@edge-runtime/ponyfill'
    
    const data = new TextEncoder().encode('Hello, world')
    const digest = await crypto.subtle.digest('SHA-256', data)
  6. Use @edge-runtime/format to format objects and primitives

    main

    To use the formatter, first initialize it using createFormat(). The resulting function can then be used to convert objects, symbols, or primitives into formatted strings. It supports multiple arguments and printf-style string substitutions (e.g., %i).

    import { createFormat } from '@edge-runtime/format'
    const format = createFormat()
    
    // Formatting a single object
    const obj = { [Symbol.for('foo')]: 'bar' }
    format(obj) // => '{ [Symbol(foo)]: 'bar' }'
    
    // Formatting multiple arguments
    format('The PI number is', Math.PI, '(more or less)') // => 'The PI number is 3.141592653589793 (more or less)'
    
    // Using printf-style substitutions
    format('The PI number is %i', Math.PI, '(rounded)') // => 'The PI number is 3 (rounded)'
  7. Use the Edge Runtime CLI modes

    main

    The Edge Runtime CLI allows you to evaluate scripts within the Edge Runtime API constraints using several different modes:

    • REPL: Start an interactive session for real-time code evaluation.
    • Eval: Evaluate a single inline string as a script.
    • Listen: Start a local HTTP server to run a specific script file.

    Use edge-runtime --help to view all available commands and flags.

    # Start an interactive REPL session
    edge-runtime --repl
    
    # Evaluate an inline script
    edge-runtime --eval "Object.getOwnPropertyNames(this)"
    
    # Run a local HTTP server using a script file
    edge-runtime --listen examples/fetch.js
  8. Run the Edge Runtime as an HTTP server

    main

    To expose your Edge Runtime locally via HTTP, use the runServer function. Pass the EdgeRuntime instance (configured with initialCode) and a port to the runServer options. This allows you to interact with your runtime using standard HTTP clients like curl.

    import { EdgeRuntime, runServer } from 'edge-runtime'
    import { onExit } from 'signal-exit'
    
    const initialCode = `
    addEventListener('fetch', event => {
      const { searchParams } = new URL(event.request.url)
      const url = searchParams.get('url')
      return event.respondWith(fetch(url))
    })
    `
    
    const edgeRuntime = new EdgeRuntime({ initialCode })
    
    const server = await runServer({ runtime: edgeRuntime, port: 3000 })
    console.log(`> Edge server running at ${server.url}`)
    onExit(() => server.close())

    Then, test it with:

    curl http://[::]:3000?url=https://example.vercel.sh