Supabase Edge Runtime splits a proxy from the code it serves
A server based on Deno runtime, capable of running JavaScript, TypeScript, and WASM services.
At a glance
- What is it?
- supabase/edge-runtime is a Rust web server built on a vendored Deno runtime that executes JavaScript, TypeScript and WASM functions. Its architecture separates a main runtime, which proxies requests and holds every environment variable, from a user runtime where memory and time limits apply and only explicitly allowed variables are visible. The project is MIT licensed, releases frequently, and labels itself beta software.
- Who is it for?
- Supabase Edge Runtime suits a team that wants to self-host Deno functions, add an authentication step in front of user code, or turn the server into a programmable HTTP proxy, and that is prepared to follow a beta project with breaking API changes. It is the wrong choice if you need a stable Node runtime, if your platform is not x86 Linux with the toolchain the Dockerfile assumes, or if you cannot track a vendored Deno fork.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two runtimes, two sets of privileges
The architecture section of the README is the whole design in a few lines, and it is unusual enough to be worth reading closely. The edge runtime is divided into two runtimes with different purposes.
The main runtime is an instance responsible for proxying transactions to the user runtime. It is meant to be an entry point before user functions run, a place where you can do authentication and other work before calling the user function. It has no user-facing limits, and it has access to all environment variables.
The user runtime is an instance responsible for executing user code. Limits have to be set for it, such as memory and timeouts, and it has access only to environment variables explicitly allowed by the main runtime.
That split is a privilege boundary, and it is the reason to run this project rather than putting a Deno process behind a reverse proxy. In a deployment where a tenant writes a function, the function does not get the service credentials, because the main runtime decides which variables cross over. The main runtime is the piece you write policies in, and the user runtime is the piece you sandbox. The cost is that the boundary only works if the allow list is configured, and the documentation available here does not show the configuration keys for it.
A sequence diagram in the assets folder illustrates the request flow, and the request path through both runtimes is the thing to understand before deploying.
Self-hosting Edge Functions or becoming an HTTP proxy
The README gives two uses for the server. The first is to locally test and self-host Supabase's Edge Functions, or any Deno function. The second is to use it as a programmable HTTP proxy, where you intercept and route HTTP requests. The second use is the one that explains the two-runtime design: a proxy that authenticates, rewrites a request and then forwards it to user code is exactly the shape the main and user runtimes describe.
The set of examples in the repository shows how broad the target is. There is a hello-world and a main-empty, an express and a fastify-v4 example for people arriving from Node, a commonjs-hono example and a commonjs-hono-websocket one, a cache-api example, a chunked-text example, an axios example, a deno-file-upload example, a custom-jwt-validation example, an event-manager example, an import-meta-dirname example, a logger-stdout example, and two embedding examples, generate-embeddings and generate-image-embeddings, alongside a gte-small-ort example that runs a model with ONNX Runtime and a k6-gte example with a separate k6 directory at the top level for load testing.
The Node-shaped examples are worth a caveat. They work because the runtime carries an ext/node extension, and the point of ext/node is compatibility, not parity. Code that depends on a Node module resolving in a particular way, or on a specific native addon, is exactly the kind of thing a Deno based runtime will treat differently, and the example set shows the surface that is known to work rather than a promise that any Node program will.
Building the binary and the container image
The build environment is Rust plus a vendored Deno tree. The workspace is declared in Cargo.toml, whose members include the deno directory itself, a set of crates for the base runtime, a memory check, a runtime base, a CPU timer, an HTTP utilities crate and a Deno facade, plus the extension crates for AI, env, event worker, node, os, runtime and workers. The Deno dependencies are pinned to exact versions, deno_core at 0.324.0 and deno_graph at 0.86.3 among them, and the workspace itself is marked edition 2021 and licence MIT.
The Dockerfile is a multi-stage build. The builder stage is based on rust:1.98.0-bookworm, installs the LLVM, BLAS and LAPACK development packages, copies the tree in and compiles it with a cached Cargo registry and target directory:
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} --mount=type=cache,target=/usr/src/edge-runtime/target,id=${TARGETPLATFORM} \
GIT_V_TAG=${GIT_V_TAG} cargo build --profile ${PROFILE} --features "${FEATURES}" && \
mv /usr/src/edge-runtime/target/${PROFILE}/edge-runtime /rootThe runtime stage is much thinner, based on debian:bookworm-slim with libssl, BLAS and LAPACK runtime libraries and ca-certificates, and the compiled binary plus a stripped debug copy are copied into /usr/local/bin. The debug symbols are split out with objcopy so that a stripped binary still carries a debug link, which is a detail worth copying into your own build pipeline if you run this in production and need stack traces.
There are ONNX Runtime variants of the image, one plain and one built with the GPU flag, and a CUDA stage based on nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04. The ONNX stages call a script in the scripts directory to install the runtime for the given platform. If you do not need the ONNX extensions, the plain image is the one to build, and the FEATURES build argument is how you select.
A vendored Deno means a fork you inherit
The repository is not a thin server in front of a Deno release. There is a deno/ directory in the tree, the workspace lists deno as a path dependency, and the pinned Deno crates include deno_core, deno_ast, deno_graph, deno_npm, deno_permissions, deno_config, deno_cache_dir and deno_lockfile, each pinned with an exact version and the equals operator. The upstream extension crates, from deno_broadcast_channel through deno_webgpu and deno_websocket, are pinned the same way.
What this buys is control. The server can add the extensions it needs, ext/ai, ext/env, ext/node, ext/os, ext/runtime and ext/workers, and it can compile the Deno internals into a single Rust binary instead of shipping a Deno executable next to it. The ext directory is where the Node compatibility, the environment variable handling and the AI helpers live.
What it costs is a maintenance obligation. The version numbers of the pinned Deno crates move in step with the Deno project, and a project that vendors a runtime has to absorb the churn when that upstream changes. The repository also carries a vendor/ directory, a nix/ directory with flake.nix and flake.lock, a .devcontainer, a deno.json, a rust-toolchain.toml, a dprint configuration and a rustfmt configuration, which is the toolchain surface of a project that builds two language runtimes and a CLI at once. The cli/ directory is the command line entry point, and DEVELOPERS.md is where the build and test instructions for contributors live.
If you adopt this, you are adopting a fork, not just a binary. That is a legitimate choice for a platform team and a heavy one for a product team.
Beta software with breaking changes, and a fast release train
The README carries a warning in capitals: beta software, with breaking changes to APIs and configuration options. That is the single most important line for anyone planning around this project, and it sits above the architecture section rather than buried in a changelog.
The release history shows the tempo. v1.77.5 was published on 2026-10-19, and v1.77.4 and v1.77.3 both landed on 2026-10-01, minutes apart. The last push was on 2026-10-19, the repository is not archived, and the version numbering tracks a Deno-like cadence where the minor number moves with the underlying runtime. Releases this frequent mean fixes arrive quickly, and they also mean a configuration file written for one patch level may need attention after the next one.
The licensing is straightforward. The workspace package metadata declares licence MIT, and the repository carries a LICENSE file, so there is no custom licence question here and no restriction on commercial use or redistribution. The project is built and maintained by the Supabase team, and it welcomes contributions through GitHub issues and Discord, following the Supabase code of conduct.
The practical operating rule that follows is to pin the exact version in your deployment rather than tracking a tag, to read the changelog before each bump, and to keep your edge function code away from APIs you do not control, because a breaking change in the runtime is cheap for you to absorb only if your own code is small.
Where a Deno runtime is the wrong tool
The clearest case is a codebase that is Node in substance rather than Node in syntax. The examples show express and fastify working, so an HTTP service written in that style will run, but the differences that bite are not in the framework, they are in the module system, the filesystem permissions model and the availability of native packages. If your service depends on a native module or on a package with a large transitive tree, the Deno permission model and npm compatibility layer become the work, not the function.
The second case is a deployment platform you do not control. The image is a Linux container built from a Rust builder stage, and the CUDA variant assumes a specific NVIDIA base image. On a platform where you cannot run that container, or where the CPU architecture is not the one the release artifacts target, you are compiling the workspace yourself, with a vendored Deno, which turns a five minute install into a build pipeline you own.
The third case is a service that needs durable state. The runtime executes a request, the user runtime is limited by memory and timeout, and the process is expected to be disposable. Anything that needs to keep state between requests belongs in a database or a queue, and if your workload is stateful by nature, an edge function is the wrong shape regardless of how well it runs.
And the fourth is a team that cannot absorb a beta. The warning about breaking changes to APIs and configuration options is not a formality here, because the release cadence is high and the configuration surface is the part that changes. Adopting this means accepting that your deployment configuration is expected to be revisited on a schedule that a vendor decides.
Editorial conclusion
Supabase Edge Runtime suits a team that wants to self-host Deno functions, add an authentication step in front of user code, or turn the server into a programmable HTTP proxy, and that is prepared to follow a beta project with breaking API changes. It is the wrong choice if you need a stable Node runtime, if your platform is not x86 Linux with the toolchain the Dockerfile assumes, or if you cannot track a vendored Deno fork. Verify first that the release you pin, currently v1.77.5, matches the Deno behaviour your functions depend on, and read the environment variable allow list the main runtime passes to the user runtime before you deploy anything that reads secrets.
Frequently asked questions
What is the difference between the main runtime and the user runtime in Supabase Edge Runtime?
The main runtime proxies requests to the user runtime, is where you do work such as authentication before user code runs, has no user-facing limits and can see all environment variables. The user runtime executes user code, must have memory and timeout limits set for it, and only sees environment variables the main runtime explicitly allows.
Can I run Supabase Edge Functions locally or self-host them?
Yes. The project lists locally testing and self-hosting Supabase's Edge Functions, or any Deno function, as a primary use, and the second listed use is acting as a programmable HTTP proxy that intercepts and routes requests. A DEVELOPERS.md in the repository covers building and testing the runtime.
What language is Supabase Edge Runtime written in and what does it run?
The runtime is written in Rust, as a Cargo workspace with crates for the base runtime, a Deno facade and extensions for AI, env, node, os, runtime and workers. It runs JavaScript, TypeScript and WASM services on a Deno runtime that is vendored into the repository.
Is Supabase Edge Runtime stable enough to depend on?
The README marks it as beta software and warns that APIs and configuration options will have breaking changes. Releases move quickly, with v1.77.5 published on 2026-10-19 and v1.77.4 and v1.77.3 both on 2026-10-01, and the last push was on 2026-10-19. The licence is MIT.
Does the Edge Runtime support Node.js style frameworks?
There are express, fastify-v4 and hono examples in the examples directory, and the workspace includes an ext/node extension for Node compatibility. That covers a good deal of Node style HTTP code, though the examples show what is known to work rather than full parity with a Node runtime.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/supabase-edge-runtime)Was this useful?