.forge.yaml Reference

Complete reference for the Forge project configuration file

.forge.yaml Reference

The .forge.yaml file is the project-level configuration for the Forge CLI. It lives at the root of your project and configures project structure, development tools, build settings, deployment targets, code generation, and testing.

This file is not the same as config.yaml (runtime application config). See Configuration for runtime config details.

JSON Schema

A JSON Schema is available for editor auto-completion and validation. Add one of the following to the top of your .forge.yaml:

# yaml-language-server: $schema=https://raw.githubusercontent.com/xraph/forge/main/schema/forge.schema.json

Or configure it in your VS Code / Cursor settings.json for all .forge.yaml files:

{
  "yaml.schemas": {
    "https://raw.githubusercontent.com/xraph/forge/main/schema/forge.schema.json": ".forge.yaml"
  }
}

The schema file is also available locally in the repository at schema/forge.schema.json.


Full Annotated Example

Below is a complete .forge.yaml with every supported field and inline documentation. All fields except project.name are optional — Forge applies sensible defaults when they are omitted.

# =============================================================================
# .forge.yaml — Forge project configuration
# Schema: https://raw.githubusercontent.com/xraph/forge/main/schema/forge.schema.json
# =============================================================================

# -----------------------------------------------------------------------------
# Project metadata and structure
# -----------------------------------------------------------------------------
project:
  name: my-project                       # Required. Project name.
  version: "1.0.0"                       # Semver version string.
  description: "My Forge application"    # Human-readable description.
  type: monorepo                         # Project type (currently only "monorepo").
  layout: single-module                  # "single-module" or "multi-module".
  module: github.com/myorg/my-project    # Go module path (required for single-module).

  # Directory structure overrides (single-module layout).
  # Omit to use Go convention defaults.
  structure:
    cmd: ./cmd                           # App entry points (default: ./cmd)
    apps: ./apps                         # App config directories (default: ./apps)
    pkg: ./pkg                           # Shared packages (default: ./pkg)
    internal: ./internal                 # Internal packages (default: ./internal)
    extensions: ./extensions             # Extensions (default: ./extensions)
    database: ./database                 # Migrations & seeds (default: ./database)
    config: ./config                     # Config files (default: ./config)
    deployments: ./deployments           # Deployment artifacts (default: ./deployments)

  # Workspace configuration (multi-module layout only).
  workspace:
    enabled: true
    apps: "./apps/*"                     # Glob for app modules
    services: "./services/*"             # Glob for service modules
    extensions: "./extensions/*"         # Glob for extension modules
    pkg: "./pkg"                         # Shared package path

# -----------------------------------------------------------------------------
# Development server and tooling
# -----------------------------------------------------------------------------
dev:
  auto_discover: true                    # Auto-discover apps in cmd/ or apps/
  discover_pattern: "./cmd/*"            # Custom discovery glob pattern
  default_app: api-gateway               # App to run when none is specified

  # File watching
  watch:
    enabled: true
    paths:                               # Glob patterns to watch
      - "./apps/**/internal/**/*.go"
      - "./pkg/**/*.go"
      - "./internal/**/*.go"
    exclude:                             # Glob patterns to exclude
      - "**/*_test.go"
      - "**/testdata/**"
      - "**/vendor/**"

  # Hot reload
  hot_reload:
    enabled: true
    delay: 500ms                         # Debounce delay before restart

  # Docker dev mode (forge dev --docker)
  docker:
    enabled: false                       # Enable Docker mode by default
    image: golang:1.25-alpine            # Base image for dev container
    dockerfile: ""                       # Custom Dockerfile (empty = auto-generate)
    network: bridge                      # Docker network
    platform: linux/amd64                # Target platform (optional)
    volumes:                             # Extra host:container volume mounts
      /tmp/go-cache: /root/.cache/go-build
    env:                                 # Extra container environment variables
      DEBUG: "true"
      LOG_LEVEL: debug
    build_args:                          # Docker build arguments
      GO_VERSION: "1.25"

# -----------------------------------------------------------------------------
# Database
# -----------------------------------------------------------------------------
database:
  driver: postgres                       # postgres, mysql, or sqlite
  migrations_path: ./database/migrations # Path to migration files
  seeds_path: ./database/seeds           # Path to seed files
  models_output: ./database/models       # Output for generated models

  connections:                           # Named database connections
    default:
      url: postgres://user:password@localhost:5432/mydb
      max_connections: 25
      max_idle: 5
    read_replica:
      url: postgres://user:password@replica:5432/mydb
      max_connections: 10
      max_idle: 2

# -----------------------------------------------------------------------------
# Build
# -----------------------------------------------------------------------------
build:
  output_dir: ./bin                      # Binary output directory
  cmd_dir: ./cmd                         # Directory with app entry points
  auto_discover: true                    # Auto-discover buildable apps
  ldflags: "-s -w"                       # Linker flags
  tags:                                  # Build tags
    - production

  # Explicit app list (overrides auto-discovery when non-empty)
  apps:
    - name: api-gateway
      cmd: ./cmd/api-gateway
      output: api-gateway
      dockerfile: docker/Dockerfile.api
    - name: worker
      cmd: ./cmd/worker
      output: worker
      module: ./apps/worker              # Multi-module path

  # Cross-compilation targets
  platforms:
    - os: linux
      arch: amd64
    - os: linux
      arch: arm64
    - os: darwin
      arch: arm64

# -----------------------------------------------------------------------------
# Deployment
# -----------------------------------------------------------------------------
deploy:
  registry: ghcr.io/myorg                # Docker registry prefix

  # Environment definitions
  environments:
    - name: dev
      namespace: dev
      variables:
        LOG_LEVEL: debug
    - name: staging
      namespace: staging
      cluster: staging-cluster
      region: us-east-1
      variables:
        LOG_LEVEL: info
    - name: production
      namespace: prod
      cluster: prod-cluster
      region: us-east-1
      variables:
        LOG_LEVEL: warn

  # Docker deployment config (forge infra docker / forge deploy docker)
  docker:
    build_context: .
    dockerfile: Dockerfile
    compose_file: docker-compose.yml
    network: forge-network
    volumes:
      pg-data: /var/lib/postgresql/data
      redis-data: /data

  # Kubernetes config (forge infra k8s / forge deploy k8s)
  kubernetes:
    manifests: ./deployments/k8s
    namespace: default
    context: my-k8s-cluster
    registry: ghcr.io/myorg

  # DigitalOcean App Platform config (forge infra do)
  digitalocean:
    region: nyc1
    app_spec_file: ./deployments/do/app.yaml
    cluster_name: my-do-cluster
    git_repo: myorg/my-project
    git_branch: main
    deploy_on_push: true

  # Render.com config (forge infra render)
  render:
    blueprint_file: ./deployments/render/render.yaml
    region: oregon
    git_repo: myorg/my-project
    git_branch: main

# -----------------------------------------------------------------------------
# Code generation
# -----------------------------------------------------------------------------
generate:
  templates_path: ./templates            # Custom template directory

  generators:                            # Per-generator overrides
    app:
      output: "./cmd/{{.Name}}"
      cmd_path: "./cmd"
    service:
      output: "./internal/services/{{.Name}}"
      create_module: false
    controller:
      output: "./internal/handlers/{{.Name}}"
      cmd_path: "./cmd"
      internal_path: "./internal"

# -----------------------------------------------------------------------------
# Extensions (pass-through config for Forge extensions)
# -----------------------------------------------------------------------------
extensions:
  auth:
    enabled: true
    default_provider: bearer
  database:
    auto_migrate: true
  cache:
    driver: redis
    ttl: 10m

# -----------------------------------------------------------------------------
# Testing
# -----------------------------------------------------------------------------
test:
  coverage_threshold: 80                 # Minimum coverage percentage
  race_detector: true                    # Enable -race flag
  parallel: true                         # Run tests in parallel
  timeout: 30s                           # Test timeout

Section Reference

project

FieldTypeDefaultDescription
namestringRequired. Project name.
versionstring""Project version (semver).
descriptionstring""Human-readable description.
typestring"monorepo"Project type.
layoutstring"single-module""single-module" or "multi-module".
modulestring""Go module path. Required for single-module.
structureobjectGo conventionsDirectory structure overrides. See structure.
workspaceobjectMulti-module workspace config. See workspace.

structure

All fields default to standard Go conventions if omitted.

FieldDefaultDescription
cmd./cmdApp entry point directory.
apps./appsApp config directories (also used for app-level .forge.yaml).
pkg./pkgShared packages.
internal./internalInternal packages.
extensions./extensionsExtension code.
database./databaseMigrations and seeds.
config./configConfig files.
deployments./deploymentsDeployment artifacts.

workspace

Used only when project.layout is "multi-module".

FieldDefaultDescription
enabledfalseEnable Go workspace mode.
apps"./apps/*"Glob for app modules.
services""Glob for service modules.
extensions""Glob for extension modules.
pkg"./pkg"Shared package path.

dev

FieldTypeDefaultDescription
auto_discoverbooltrueAuto-discover apps.
discover_patternstring"./cmd/*"Discovery glob pattern.
default_appstring""Default app when none specified.
watchobjectFile watching config. See watch.
hot_reloadobjectHot reload config. See hot_reload.
dockerobjectDocker dev config. See docker (dev).

watch

FieldTypeDefaultDescription
enabledbooltrueEnable file watching.
pathsstring[]["./apps/**/internal/**/*.go", "./pkg/**/*.go", "./internal/**/*.go"]Glob patterns to watch.
excludestring[]["**/*_test.go", "**/testdata/**", "**/vendor/**"]Glob patterns to exclude.

hot_reload

FieldTypeDefaultDescription
enabledbooltrueEnable hot reload.
delayduration500msDebounce delay before restart.

docker (dev)

Configuration for forge dev --docker. See the Docker Development Mode docs for full usage.

FieldTypeDefaultDescription
enabledboolfalseEnable Docker mode by default.
imagestringgolang:1.25-alpineBase Docker image.
dockerfilestring""Custom Dockerfile path (empty = auto-generate).
networkstringbridgeDocker network name.
platformstring""Target platform (e.g., linux/amd64).
volumesmap[string]string{}Extra volumes (host path → container path).
envmap[string]string{}Extra environment variables.
build_argsmap[string]string{}Docker build arguments.

database

FieldTypeDefaultDescription
driverstring"postgres"Database driver: postgres, mysql, or sqlite.
migrations_pathstring"./database/migrations"Migration files directory.
seeds_pathstring"./database/seeds"Seed files directory.
models_outputstring"./database/models"Generated models output.
connectionsmap[string]object{}Named connections. Each value has url, max_connections, max_idle.

build

FieldTypeDefaultDescription
output_dirstring"./bin"Binary output directory.
cmd_dirstring"./cmd"Directory with entry points.
auto_discoverbooltrueAuto-discover buildable apps.
ldflagsstring""Linker flags for go build.
tagsstring[][]Build tags.
appsBuildApp[][]Explicit app list. See apps (build).
platformsPlatform[][]Cross-compilation targets.

apps (build)

FieldTypeRequiredDescription
namestringYesApplication name.
modulestringNoGo module path (multi-module).
cmdstringNoPath to main.go directory.
outputstringNoBinary output name.
dockerfilestringNoDockerfile path.

platforms

FieldTypeRequiredDescription
osstringYeslinux, darwin, or windows.
archstringYesamd64, arm64, or 386.

deploy

FieldTypeDefaultDescription
registrystring""Docker registry prefix.
environmentsEnvironmentConfig[][]Environment definitions.
dockerobjectDocker deployment config.
kubernetesobjectKubernetes config.
digitaloceanobjectDigitalOcean config.
renderobjectRender.com config.

environments

FieldTypeRequiredDescription
namestringYesEnvironment name (e.g., dev, staging, production).
clusterstringNoKubernetes cluster name.
namespacestringNoKubernetes namespace.
regionstringNoCloud region.
variablesmap[string]stringNoEnvironment variables.

docker (deploy)

FieldTypeDefaultDescription
build_contextstring"."Docker build context.
dockerfilestring"Dockerfile"Dockerfile path.
compose_filestring"docker-compose.yml"Compose file path.
networkstring""Docker network name.
volumesmap[string]string{}Named volumes.

kubernetes

FieldTypeDefaultDescription
manifestsstring"./deployments/k8s"Manifests directory.
namespacestring"default"Default namespace.
contextstring""kubectl context.
registrystring""Image registry.

digitalocean

FieldTypeDefaultDescription
regionstring""DO region (e.g., nyc1).
app_spec_filestring""App spec file path.
cluster_namestring""DOKS cluster name.
git_repostring""GitHub repo (owner/repo).
git_branchstring"main"Branch to deploy.
deploy_on_pushboolfalseAuto-deploy on push.

render

FieldTypeDefaultDescription
blueprint_filestring""Render blueprint path.
regionstring""Render region.
git_repostring""GitHub repo (owner/repo).
git_branchstring"main"Branch to deploy.

generate

FieldTypeDefaultDescription
templates_pathstring"./templates"Custom template directory.
generatorsmap[string]object{}Per-generator overrides.

Each generator entry supports:

FieldTypeDescription
outputstringOutput path template.
cmd_pathstringOverride cmd path (single-module).
internal_pathstringOverride internal path (single-module).
create_moduleboolCreate a Go module (multi-module).
module_pathstringModule path template (multi-module).

extensions

The extensions key is a free-form map. Keys are extension names, values are extension-specific configuration objects. These values are passed through to extensions at runtime.

extensions:
  auth:
    enabled: true
    default_provider: bearer
  cache:
    driver: redis
    ttl: 10m

test

FieldTypeDefaultDescription
coverage_thresholdint80Minimum coverage percentage (0–100).
race_detectorbooltrueEnable -race flag.
parallelbooltrueRun tests in parallel.
timeoutduration30sTest timeout.

App-Level .forge.yaml

Individual apps can have their own .forge.yaml at apps/<name>/.forge.yaml. This file overrides project-level settings for that specific app. A JSON Schema is also available at schema/forge-app.schema.json.

# yaml-language-server: $schema=https://raw.githubusercontent.com/xraph/forge/main/schema/forge-app.schema.json

# apps/api-gateway/.forge.yaml
app:
  name: api-gateway
  type: web
  version: "1.0.0"

dev:
  port: 8080
  host: localhost
  env_file: .env.api
  docker:
    image: golang:1.25-bookworm
    network: api-network
    env:
      SERVICE_NAME: api-gateway

build:
  output: api-gateway
  dockerfile: docker/Dockerfile.api
  tags:
    - jsoniter
  ldflags: "-X main.version=1.0.0"

App Config Fields

FieldTypeDescription
app.namestringRequired. Application name.
app.typestringApp type: web, cli, worker, grpc.
app.versionstringApp version.
dev.portintDev server port.
dev.hoststringDev server host (default: localhost).
dev.env_filestringPath to .env file.
dev.dockerobjectDocker dev overrides (same schema as project-level dev.docker).
build.outputstringBinary output name.
build.dockerfilestringDockerfile path.
build.tagsstring[]Build tags.
build.ldflagsstringLinker flags.

Minimal Examples

Minimal Single-Module

The smallest valid .forge.yaml:

project:
  name: my-api
  module: github.com/me/my-api

Everything else uses convention defaults: cmd/ for entry points, ./bin for output, postgres driver, hot reload enabled, etc.

Minimal Multi-Module

project:
  name: my-platform
  layout: multi-module
  workspace:
    enabled: true
    apps: "./apps/*"

With Docker Dev

project:
  name: my-api
  module: github.com/me/my-api

dev:
  docker:
    network: my-network
    env:
      DEBUG: "true"

With Full Deploy Pipeline

project:
  name: my-platform
  module: github.com/me/my-platform

deploy:
  registry: ghcr.io/me

  environments:
    - name: dev
      namespace: dev
    - name: production
      namespace: prod
      region: us-east-1

  kubernetes:
    context: prod-cluster

How is this guide?

On this page