Forge Documentation
Forge is a Rust framework that compiles backend functions (queries, mutations, jobs, crons, workflows, and webhooks) into a single runtime backed by PostgreSQL. It generates frontend bindings from the same Rust source of truth, with first-class support for SvelteKit and Dioxus today.
Documentation map
- Start: First App, Project Anatomy
- Build: Queries, mutations, jobs, workflows, scheduled tasks, webhooks, and reactivity
- Connect: Generated TypeScript client, authentication, caching, and frontend usage
- Ship: Configuration, deployment, and testing
- Scale: Multiple nodes, worker pools, and global deployments
- Reference: CLI and configuration options
Quick start (development)
curl -fsSL https://tryforge.dev/install.sh | sh
forge new my-app --template with-svelte/minimal
cd my-app
forge dev
Runs Docker Compose with PostgreSQL, backend (cargo-watch), and the selected frontend target. Use forge dev down --clear to reset. Choose a with-dioxus/* template if you want a Dioxus frontend instead of SvelteKit.
Queries and mutations
#[forge::query]
pub async fn list_todos(ctx: &QueryContext) -> Result<Vec<Todo>> {
sqlx::query_as!(Todo, "SELECT * FROM todos")
.fetch_all(ctx.db())
.await
.map_err(Into::into)
}
// Auto-generated, type-safe
import { listTodos$ } from '$lib/forge';
const todos = listTodos$();
Queries and mutations are exposed as RPC endpoints under /_api/rpc and used by the
generated frontend bindings. SvelteKit projects get TypeScript clients and stores; Dioxus
projects get Rust bindings and hooks. Subscriptions use PostgreSQL LISTEN/NOTIFY plus a
SSE connection to push updates.
Background jobs
#[forge::job(
priority = "high",
retry(max_attempts = 5, backoff = "exponential")
)]
pub async fn send_email(ctx: &JobContext, args: EmailArgs) -> Result<()> {
ctx.progress(0, "Sending...")?;
// ...
ctx.progress(100, "Sent")?;
Ok(())
}
Jobs are stored in PostgreSQL and claimed with FOR UPDATE SKIP LOCKED. Retry policy,
priority, and progress updates are stored alongside the job record.
Webhooks
#[forge::webhook(
path = "/hooks/stripe",
signature = WebhookSignature::hmac_sha256("Stripe-Signature", "STRIPE_WEBHOOK_SECRET"),
idempotency = "header:Idempotency-Key",
)]
pub async fn stripe(ctx: &WebhookContext, payload: Value) -> Result<WebhookResult> {
ctx.dispatch_job("process_payment", payload.clone()).await?;
Ok(WebhookResult::Accepted)
}
Webhook handlers run inside the Forge runtime and can validate signatures, enforce idempotency, and enqueue background work.
Workflows
#[forge::workflow]
pub async fn onboarding(ctx: &WorkflowContext, user_id: Uuid) -> Result<()> {
ctx.step("welcome_email", || async {
send_welcome(user_id).await
})
.run()
.await?;
ctx.sleep(Duration::from_secs(3 * 24 * 60 * 60)).await?;
ctx.step("check_activation", || async {
check_user_active(user_id).await
})
.compensate(|_| async move { send_reminder(user_id).await })
.run()
.await?;
Ok(())
}
Workflow state is persisted in PostgreSQL so steps resume after restarts. Durable timers and compensation handlers are recorded per step.
PostgreSQL integration
Forge relies on core PostgreSQL features for coordination and data propagation:
FOR UPDATE SKIP LOCKEDfor job queuesLISTEN/NOTIFYfor real-time subscriptions- Advisory locks for leader election and migration coordination
- WAL durability for workflow and job state
sqlxmacros plus.sqlx/offline cache for compile-time query validation
Build output
cargo build --release
./target/release/my-app
The release binary embeds the Forge runtime and can optionally bundle the frontend build
using the embedded-frontend feature.
Requirements
Forge requires PostgreSQL 15+ and is released under the MIT License.
Next: First App