---
title: "Forge"
tagline: "Go framework"
language: "Go"
license: "MIT"
since: "2025"
canonical: "https://xraph.com/work/forge"
---

# Forge

An opinionated Go framework: DI container, router, layered config, health checks, migrations and ordered shutdown, plus around twenty extensions you switch on when you need them: Postgres and Mongo, Kafka, MQTT, gRPC, GraphQL, WebRTC, Raft consensus, MCP. `forge init` scaffolds, `forge dev` hot-reloads. Everything else at xraph is built on it.

## Install

```bash
go get github.com/xraph/forge
```

## What it is

Forge is the Go framework the rest of this stack is built on. It bundles the decisions every backend service makes before it serves a request, covering dependency injection, routing, configuration, health checks, migrations, observability and shutdown ordering, then puts everything else behind an extension interface you opt into.

The premise is that those decisions are not interesting and I had made all of them before, slightly differently each time. Deciding them once and living with the consequences across every service turned out to be worth more than the flexibility I gave up.

## The core

- **Dependency injection** through Vessel: generic type-safe resolution, uber/dig-style constructor injection, and circular-dependency detection at registration time.
- **Lifecycle as a graph.** Services declare what they depend on; the container computes a start order and reverses it for shutdown. A failed start halts the boot naming the dependency it needed.
- **Configuration** through Confy: YAML, JSON or TOML, environment overrides, hot reload, and auto-discovery that walks up the tree to find a monorepo's config.
- **Health** discovered rather than registered. Any service implementing the interface shows up at /\_/health without a list to maintain.
- **Observability** from the first handler: structured logs, Prometheus at /\_/metrics, and trace propagation.

## Extensions

Around twenty ship in-tree, each with the same registration and lifecycle shape, so learning one teaches you the others: AI (LLM integration, agents, inference), Auth (OAuth, JWT, SAML), Cache (Redis, Memcached, in-memory), Consensus (Raft), Database (Postgres, MySQL, SQLite, MongoDB), Events (bus and sourcing), GraphQL, gRPC with reflection, HLS, Kafka, MCP, MQTT, oRPC, Queue, Search (Elasticsearch, Typesense), Storage (S3, GCS, local), Streaming (WebSocket, SSE, WebRTC).

The extension interface has one required method. Anything else, including migrations, health and route registration, is an optional interface detected by type assertion. That was a correction: the first version required seven methods and most implementations satisfied five of them with empty bodies.

## The CLI

forge init scaffolds a project from a template. forge dev runs it with hot reload. There is code generation for handlers, controllers and services, a migration runner with versioning and cross-module ordering, and a test runner with coverage.

## Where it fits

The industrial work I do runs on it, with each capability as a separate extension so a deployment only starts the parts it uses. Bastion, Authsome, Cortex, Weave, Warden, Vault, Keysmith, Chronicle, Ledger, Dispatch and Relay all ship a Forge extension alongside a standalone constructor.

The standalone path is not a courtesy. If those libraries only worked inside Forge, Forge's assumptions would leak into their designs without anything failing to warn me.

---

*Unpublished draft. Not peer reviewed and not submitted to a venue.*


## Anatomy

- **Container**: Type-safe dependency injection with cycle detection at registration.
- **Lifecycle**: Services declare dependencies; start and shutdown order is computed, not written.
- **Configuration**: Layered sources with typed access and hot reload.
- **Extensions**: Everything beyond the core is opt-in behind one interface.

## Constraints and trade-offs

- (decision) Decide the boring parts once and live with it. The flexibility given up was worth less than the consistency gained.
- (constraint) Health, metrics and info are mounted before application code runs. A service cannot ship without them.
- (trade-off) A framework, not a library. Adopting one piece means adopting the lifecycle it assumes.
