This guide is for repository administrators and application builders. It explains how to configure and operate an application in the current Alpha. For the product boundary, release model, and operator-facing contracts, see the Forge Deploy overview.
Forge Deploy turns an exact SmolForge Git commit into a public application at
{project}.sites.smol.ai. The current Alpha supports immutable static
assets, an HTTP Worker, Forge-managed durable state, and bounded realtime
without asking an application author to provision Cloudflare resources.
The Alpha is available to eligible public repositories whose administrator has
accepted the current Forge Deploy Terms and whose account and project have
Alpha access. It is a real hosted service, but sites.smol.ai is a
pre-production domain and the runtime contract may change before general
availability. A claimed hostname remains reserved to its original project and
is not reassigned, while Forge may suspend serving or revoke retained Alpha
content.
Cloudflare provides the runtime, storage, networking, and state primitives that make Forge possible. Forge Deploy adds a Git-native release control plane above them:
| Deployment concern | Direct provider deployment | Forge Deploy |
|---|---|---|
| Source identity | The command publishes whatever code and generated assets are present in the invoking checkout. | Forge reads one exact pushed Git SHA and freezes its configuration, application code, and assets into one deployment. |
| Before production | A deploy command may update the live Worker and bundled frontend together. | Every successful build receives an immutable preview. Provider publication, preview readiness, and production activation remain separate states. |
| Stale releases | Preventing an older checkout from becoming production depends on release procedure. | Automatic activation rechecks that the exact SHA is still the configured branch head and that protection policy and required checks still pass. |
| Partial provider success | If the provider changes traffic but the client loses the final receipt, operators must determine which side committed. | Forge retains the activation intent. A retry recognizes the exact target already active, records the provider receipt, and completes the Forge pointer without switching traffic again. A different active version fails closed. |
| Rollback and evidence | Operators correlate Git, build output, provider versions, and traffic changes themselves. | Forge records source, configuration, build, provider, preview, and activation evidence together. Rollback moves the production pointer to a prior ready deployment without rebuilding or rewinding durable state. |
Forge does not replace Cloudflare's platform. It removes common deployment footguns by withholding provider credentials from repository builds, publishing immutable candidates before traffic changes, and making deliberate promotion or rollback explicit and auditable. Connected Cloudflare applications can retain their existing bindings and production domain while adopting this release workflow.
Forge's API and web application are the first platform dogfood target for this
release model. Their checked-in forgeBuild.ts imports the API Worker's
Wrangler configuration as inert data, builds one exact Forge commit, and
publishes an immutable connected Worker Version without changing traffic.
A platform administrator verifies that candidate through its Forge preview before promoting it. Production activation:
If Cloudflare commits the traffic change but the final receipt read fails, the same promotion is safe to retry. Forge recognizes the exact target already active, records the provider receipt, and completes its own production pointer without changing traffic again. If a different version became active, the expected-current fence fails closed instead.
Forge requires Cloudflare's standalone per-version Preview URL before a
connected release becomes ready. It enables Preview URLs on the approved
Worker, preserves the existing workers.dev setting, and never stages preview
candidates into the production deployment. Because Cloudflare does not
generate those URLs for Workers that implement Durable Objects, Forge keeps one
bounded 0%-traffic candidate addressable through a version override while
production remains at 100%. Publishing another such candidate replaces the
preview slot, so historical Durable Object previews are not immutable archives.
Keep the Durable Object behind a separately connected service when retained
previews matter.
forge.smol.ai remains attached directly to the API Worker. It is not served
through the user-content Sites edge, so a Sites routing failure cannot hide the
control plane. Wrangler administrator access remains an independent
provider-level recovery path. Forge owns the normal exact-SHA release and audit
workflow; Cloudflare remains the runtime and the final break-glass authority.
This split is deliberate. Self-deployment should prove Forge's release contract against its own application without making the application its only means of recovery.
Install the public authoring package for editor types and local validation:
npm install --save-dev @smolai/forgeAdd forgeBuild.ts at the repository root:
import { defineForge } from '@smolai/forge/config';
export default defineForge({
version: 1,
name: 'my-app',
app: {
entrypoint: 'src/server.ts',
assets: {
directory: 'dist',
fallback: 'index.html',
},
},
routes: [
{ pattern: '/api/*', to: 'app.http' },
{ pattern: '/*', to: 'app.assets' },
],
});The manifest is the checked-in build contract, not an activation switch. After
committing it, open the repository's Sites page, create the corresponding
Deploy project, accept the current Deploy Terms, and enable the project.
npx smolforge deploy check validates the file locally and cannot confirm those
account- and repository-level steps.
Check the configuration locally, then push normally:
npx smolforge deploy check
git push origin mainForge reads and statically evaluates forgeBuild.ts from the exact pushed
commit before scheduling repository code. The evaluator accepts a deliberately
small data-only TypeScript subset; it never imports or executes the repository
file. See the complete forgeBuild.ts v1 specification and
the versioned, structural
JSON Schema. The schema is
useful for tooling; smolforge deploy check remains the authoritative local
syntax and semantic check.
Monorepos keep one forgeBuild.ts in every configured project root. They may
also add a static root .forge/config.json to list project roots, defaults,
and reviewed Cloudflare binding proposals without executing repository code.
Inspecting and importing that file does not enable a project or apply provider
state. See Repository configuration and its
JSON Schema.
forge.yml and forge.yaml are no longer accepted for new deployments. Existing live
deployments remain online until they are replaced, rolled back, disabled, or
suspended.
Forge owns the provider topology. Application code uses env.forge rather than
choosing Workers, Durable Objects, namespaces, or provider credentials.
An entrypoint exports one object with an asynchronous fetch method:
export default {
async fetch(request, env) {
const url = new URL(request.url);
const counter = env.forge.state.scope('counter/main');
if (request.method === 'GET' && url.pathname === '/api/counter') {
const snapshot = await counter.snapshot({
topic: 'value',
prefix: 'counter/',
});
const value = snapshot.entries
.find(({ key }) => key === 'counter/value')?.value ?? 0;
return env.forge.realtime.snapshotResponse(request, {
type: 'forge-snapshot',
data: { value },
cursor: snapshot.realtimeCursor,
});
}
if (request.method === 'POST' && url.pathname === '/api/increment') {
return Response.json(await counter.mutate([
{ increment: { key: 'counter/value', delta: 1 } },
{ emit: { topic: 'value', event: { type: 'incremented' } } },
]));
}
if (request.method === 'GET' && url.pathname === '/api/subscribe') {
return env.forge.realtime.authorize(request, {
scope: 'counter/main',
topic: 'value',
});
}
return Response.json({ error: 'Not found' }, { status: 404 });
},
};scope(name) provides get, list, snapshot, and atomic mutate.
Mutations support assertAbsent, assertVersion, put, delete,
increment, and state-bound emit. All operations in one mutation either
commit together or fail together. Production state is stable across code
deployments and rollbacks; preview state is isolated by deployment.
Browser pages load the versioned /.forge/client.js SDK and subscribe using an
application authorization endpoint plus an authoritative snapshot endpoint.
The SDK connects and buffers before fetching the snapshot, detects gaps, and
resynchronizes automatically. See the complete
application runtime contract and the
realtime fixture source.
Buildless repositories can use Forge's trusted fast path. Forge reads
forgeBuild.ts, committed assets, and a self-contained JavaScript entrypoint
directly from its Git object store, then reuses content-addressed artifacts.
Repositories with build commands, TypeScript compilation, imports, or generated
assets continue through the restricted exact-SHA sandbox.
The three conformance fixtures improved from 12.7–15.2 seconds to 2.6–2.7 seconds from deployment creation to live publication:
| Fixture | Before | Current | Improvement |
|---|---|---|---|
| Static SPA | 12.747 s | 2.674 s | 4.8× |
| Durable reservations | 15.210 s | 2.558 s | 5.9× |
| Durable realtime | 14.779 s | 2.719 s | 5.4× |
Try the live fixtures:
Each fixture explains the behavior it proves and links to its own SmolForge source repository.
The repository file is authoritative by default. A repository administrator may explicitly override the build command, asset directory, or SPA fallback in Forge. The Deploy page shows both source and effective values and records who configured each override.
Saving an override never silently deploys. The administrator chooses Save only or Save and deploy current branch head for every edit.
Production publication defaults to automatic after a successful eligible push. Manual publication, redeploy, promotion, rollback, and immediate disablement remain available.
Automatic production publication is additionally gated by Forge's protected branch baseline: the exact source SHA must still be the configured branch head, required Forge checks must pass, and the project's protection policy must allow automatic activation. A successful build still receives an immutable preview when production activation is blocked.
Rolling back moves the active code and asset pointer without rebuilding. It increments the runtime generation, invalidates old subscription tickets, and drains affected realtime connections. Production durable state is deliberately not rewound.
An eligible repository administrator completes the controlled-trial flow in the repository's Deploy page:
Making an enabled source private, unlisted, deleted, or suspended immediately stops production and preview serving, tickets, state mutations, and realtime connections. Making it public again does not silently re-enable the site; an administrator must explicitly enable it.
Every preview has a seven-day retention deadline. Forge retains the two newest successful rollback candidates for each site, then deletes expired immutable assets, Forge-managed runtime scripts, and Forge-published connected-account Worker Versions in retryable batches while preserving deployment, provider receipt, and cleanup history. Connected version retirement shares the per-Worker activation fence, rechecks current provider deployment membership immediately before deletion, removes the exact version from a zero-percent preview slot when necessary, and treats an already-absent version as successful reconciliation. The 100-percent production version is never a cleanup target. Forge never deletes the Worker, routes, domains, schedules, or bound KV, D1, R2, and Durable Object data. Running deployments, the active deployment, and the two newest successful rollback candidates are never selected for cleanup.
Preview URLs use 128 bits of randomness, are unauthenticated, unlisted, and
served with noindex. This provides discovery resistance, not confidentiality.
Do not put secrets or private data in a preview.
The current release intentionally excludes private-source builds, runtime secrets, custom domains, arbitrary Workers or Durable Object classes, repository-controlled provider bindings, and unrestricted outbound networking. Runtime egress is denied by default. Resource, connection, event, recipient, session, and byte ceilings are enforced by Forge rather than by application cooperation. Access and quota denials are terminal: the browser SDK does not turn an authorization or cost refusal into repeated WebSocket or polling traffic.
The trial records configuration, exact SHA, build phases, provider versions, activation/rollback, access changes, runtime invalidation, usage, and retention operations. These receipts let an operator distinguish a successful build from provider publication, preview readiness, production activation, and live hostname verification.
The 2026-07-24 Phase 0–2 release gate proved:
201 and nine 409
responses;429
realtime_quota;For deeper implementation and security details, see the Deploy documentation index.