Deno logoDeno

Isolate Config

To handle your HTTP requests or events on Deno Deploy Subhosting, the Deno Deploy system requires information on what code to run, and how it should be configured. This is called the isolate configuration.

The information contained inside of the isolate configuration can be broken down into these three sections:

  • what source code to execute
  • what environment variables the code should have access to
  • what permissions the executing code has (like network access)

Each of these sections is described in detail below.

Attributes

Source code

The source code configuration describes what code should be executed in the isolate, and how it should be loaded.

Deno Deploy natively supports and understands the ECMAScript module system (ESM). This means that Deno Deploy can load fully fledged ECMAScript module graphs without having to losslessly serialize them into a single file using a naive bundler. This aids in debuggability, and is much simpler for users to understand.

To load a full ESM module graph into a Deno Deploy isolate, the module graph must be serialized into an ESZIP file. ESZIP is a proprietary file format built for Deno Deploy that can losslessly serialize an ECMAScript module graph. It can be created from either JavaScript, TypeScript, or Rust, using the eszip library. Examples for the TypeScript API for ESZIP can be found in the repo.

In addition to ESZIP, Deno Deploy also supports loading individual JS files as bundles. This is useful for testing and debugging, or for glue code that stitches modules together that are stored in an ESZIP.

Layers

Deno Deploy Subhosting supports building the final module graph loaded in the isolate from multiple stacked partial module graphs. This is useful for when you have to load both user code, and some platform code that is shared between users. By splitting this module graph into multiple layers, you can iterate on the platform code without having to rebuild the user code layer each time.

Each layer can either be an ESZIP file, or an individual JS file. Before module loading starts in the isolate, all layers are combined into a single unified module graph. If there are multiple modules with the same specifier across layers, the module from the first specified layer is used.

Each layer has an associated ID. These IDs must be globally unique for a given subhoster. This ID is used to load the raw bytes of the layer from the /layer origin RPC endpoint.

It is possible to return a single layer (the inline layer) as the response body of a /boot origin RPC call. If this is the case, the relevant layer will be not be loaded from the /layer origin RPC endpoint. To do this, specify an ID for the inline layer in the "inline_layer" attribute of the isolate configuration, and set the ID of the layer inside of the "layers" array to that ID.

Configuration

The configuration parameters relevant to the source code configuration are:

interface IsolateConfig {
  /** The module specifier for the entrypoint module. The module loading
   * algorithm starts at this module and traverses the module graph until all
   * (transitive) dependencies of the entrypoint module are loaded. */
  entrypoint: string;

  /** The different source code layers to load modules from. Layers can be
   * defined as either ESZIP or individual JS files. Any combination of eszip
   * and JS file layers is supported. Multiple layers can be defined in any
   * combination of layer types. Before module loading in the isolate begins,
   * all layers are joined together into a single ESM module graph. In case
   * multiple layers define the same module (i.e. the same module specifier),
   * priority is given to layers that are defined first in this array.
   *
   * Each layer has an ID that is used to load the raw bytes representing the
   * layer, either from the /layer origin RPC endpoint, or from the inline layer
   * on the /boot origin RPC endpoint.
   */
  layers: Layer[];

  /** An ID for the inline layer passed as the /boot origin RPCs response body,
   * if it is specified. */
  inline_layer?: string;
}

type Layer = BundleLayer | EszipLayer;

interface BundleLayer {
  kind: "bundle";
  id: string;
  specifier: string;
}

interface EszipLayer {
  kind: "eszip";
  id: string;
}

Environment variables

Environment variables are specified in the isolate configuration as a string to string map. The keys are the environment variable names, and the values are the environment variable values.

Environment variable names must not be empty, and may not contain the = character.

interface IsolateConfig {
  /** Key value pairs of environment variables to set in the isolate. */
  envs?: Record<string, string>;
}

Permissions

Network access in the isolate can be restricted using the permissions configuration. Valid configuration values are:

  • Allow all network access.
  • Deny all network access.
  • Allow list of specific endpoints to connect to.

Network endpoints can be specified as hostnames. If a list of hostnames is specified, Deno Deploy will only allow access to those hostnames.

interface IsolateConfig {
  /** The network permissions to use in the isolate. */
  permissions?: Permissions;
}

interface Permissions {
  // List of allowed network endpoints.
  //
  // true = allow all (default)
  // false = deny all
  // [] = allow no network access
  // ["google.com"] = allow connecting to google.com
  net?: string[] | boolean;
}

Examples

Loading an individual JS file

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "bundle",
      "id": "5a40b5a2-5f66-4ab4-b516-899652f052ff",
      "specifier": "file:///src/main.js"
    }
  ]
}

Loading an ESZIP file

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "eszip",
      "id": "90ebcb76-71b2-4cc6-86aa-e4a3f597ae03"
    }
  ]
}

Loading an inline layer

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "bundle",
      "id": "812a2873-7aa8-46a0-9b97-bbace05de91d",
      "specifier": "file:///src/main.js"
    }
  ],
  "inline_layer": "812a2873-7aa8-46a0-9b97-bbace05de91d"
}

Loading two eszip layers

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "eszip",
      "id": "platform:v1"
    },
    {
      "kind": "eszip",
      "id": "user:5a40b5a2-5f66-4ab4-b516-899652f052ff"
    }
  ]
}

Specifying environment variables

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "eszip",
      "id": "user:5a40b5a2-5f66-4ab4-b516-899652f052ff"
    }
  ],
  "envs": {
    "DATABASE_URL": "postgres://user:password@hostname/db"
  }
}

Denying all network access

{
  "entrypoint": "file:///src/main.js",
  "layers": [
    {
      "kind": "eszip",
      "id": "user:5a40b5a2-5f66-4ab4-b516-899652f052ff"
    }
  ],
  "permissions": {
    "net": false
  }
}