Skip to main content
Concepts

Deploy Model

How Odyn builds, uploads, and serves your code through the CDN.

Odyn uses a build-then-upload pipeline: source files are bundled on the server, uploaded to Cloudflare R2, and served through a Cloudflare Worker at the edge. Every save-and-deploy cycle follows the same deterministic path regardless of deployment mode.

Pipeline Stages

Deploy Pipeline
Source files (editor)
       |
    Validate ---- errors shown in Problems panel
       |
    Sort files --- by sort_order, then alphabetically
       |
    Combine ------ file markers added for error mapping
       |
    esbuild ------ bundle, minify (production only), tree-shake (per-file only)
       |
    Upload ------- Cloudflare R2
       |
    Update KV ---- version pointer (production only)
       |
    Serve -------- Cloudflare Worker at edge

Validate

The build system checks for syntax errors, unresolved imports, and file constraint violations before invoking esbuild. If any check fails, the deploy is rejected and the Problems panel reports the error with the source file, line number, and a code snippet around the failure.

Sort

Files are ordered by their sort_order value (set via drag-and-drop in the file tree), then alphabetically within the same sort order. This ordering determines the concatenation sequence in bundled mode and the execution order in per-file mode.

Bundle

esbuild processes the sorted files with these settings:

SettingStagingProduction
MinifyNoYes
Source mapsInlineNone
TargetES2020ES2020
Tree-shakingMode-dependentMode-dependent

In bundled mode, output is a single IIFE. In per-file mode, output is ES modules with automatic code splitting. In folder bundle mode, each marked folder produces its own IIFE.

Upload

Built assets upload to Cloudflare R2. Staging writes to a fixed path that overwrites on each deploy. Production writes to a versioned path keyed by timestamp, preserving all previous versions.

Version Pointer

For production deploys, a Cloudflare KV entry maps the project's floating alias (@latest) to the newly uploaded version. Pinned version entries are also written so that @{versionNumber} URLs resolve correctly. See Version Pinning vs Floating Aliases.

Staging vs Production

Staging and production are separate environments with different storage, caching, and versioning behavior.

BehaviorStagingProduction
R2 pathFixed, overwritten each deployVersioned, never overwritten
KV pointerNone@latest and @{version}
Cache headersno-cacheImmutable
Source mapsInlineNone
MinificationOffOn
Rate limit60/min (auto-deploy)10/5min

Staging is designed for fast iteration: deploy, refresh, verify. Production is designed for reliability: immutable assets, versioned URLs, edge caching.

Three Deployment Modes

Odyn supports three modes that affect how esbuild processes files and what URLs appear in the embed code.

  • Bundled (default): All JS concatenated into a single IIFE (bundle.js), all CSS into bundle.css.
  • Per-file: Each entry point produces its own ES module. Shared code is split into chunks automatically.
  • Folder bundle: Folders marked as bundles produce isolated IIFE outputs.

See Deployment Modes Reference for embed examples and the mode comparison table.

Deploy Lock

Only one deploy can run at a time per project per environment. A Postgres-based lock with a 60-second TTL prevents concurrent esbuild invocations from corrupting output. If a deploy is already in progress, the API returns 409. Stale locks auto-expire if a process crashes. See Deployment Lock Contention.

Build Metadata

Each deployment stores metadata in the deployments.metadata JSONB column:

  • buildStats: per-language size breakdown (JS size, CSS size, total)
  • deploySummary: file counts by category (bundled, per-file, excluded)
  • fileHashes: content hashes for cache busting

See Build Metadata Reference for the full schema.