Skip to content

Crate Structure

Thunder is organized as a Rust workspace with four crates. Each crate has a focused responsibility and a clear position in the dependency graph.

cli (edge-cli) -> binary: thunder
|-- server (edge-server)
| |-- functions
| | `-- runtime-core
| `-- runtime-core
|-- functions
`-- runtime-core

The cli crate is the top-level entry point. It depends on all three library crates and produces the thunder binary. The server crate depends on functions and runtime-core. The functions crate depends on runtime-core. runtime-core sits at the bottom of the graph and has no in-workspace dependencies.

The foundation layer. Provides the V8 isolate primitives and everything needed to execute JavaScript and TypeScript code inside a sandboxed environment.

AreaContents
V8 integrationIsolate creation, snapshot support, heap and CPU limits
Deno extensionsRegistered ops for fetch, timers, crypto, console, and more
Module loaderCustom ModuleLoader that resolves from ESZIP bundles
SSRF protectionIP-range blocklist applied at the DNS-resolution layer
Bootstrapbootstrap.js — sets up the global scope before user code runs
Node.js polyfills42 Node.js built-in module polyfills (fs, path, crypto, buffer, etc.)
thunder:testingBuilt-in test library for function authors
thunder:httpHTTP response helpers and request utilities

Manages the lifecycle of deployed functions and the pool of isolates that serve them.

AreaContents
FunctionRegistryConcurrent registry backed by DashMap for lock-free reads
Isolate poolLRU-evicted pool of warm isolates per function
Lifecycle managementDeploy, update, undeploy, and health-check operations
Handler dispatchRoutes an inbound request to the correct isolate and invokes the JS handler
Resource trackingPer-request tracking of memory, open handles, and pending futures
Connection managerManages per-function connection concurrency and backpressure

The networking layer. Accepts connections, applies policies, and forwards valid requests into the function layer.

AreaContents
Dual-listener HTTP serverSeparate ingress (user traffic) and admin (operator traffic) listeners
Admin routerREST endpoints for deploy, undeploy, status, health, and configuration
Ingress routerPath-based routing that extracts the function name from the first segment
TLSDynamicTlsAcceptor with runtime-reloadable certificates via Rustls
Rate limitingToken-bucket rate limiter applied per source IP
Body size limitsConfigurable maximum request body size, enforced before buffering
Graceful shutdownDrains in-flight requests on SIGTERM / SIGINT before stopping

The user-facing command-line interface that wires everything together and produces the thunder binary.

AreaContents
CLI frameworkBuilt with clap (derive API)
start commandLaunches the dual-listener server
bundle commandPacks a function into an ESZIP archive
watch commandFile-watcher mode for local development with automatic reload
test commandRuns thunder:testing suites inside an isolate
check commandType-checks TypeScript source without executing
OpenTelemetry setupInitializes tracing and metrics exporters at startup