Monorepo Configuration Support
When one repository contains several services, you can describe each service in project.toml and select the one you work on. Forge then gives the AI agent the service's metadata, such as its language and framework, on top of the project-wide metadata.
When to use monorepo mode
Use monorepo mode when your repository contains several independently buildable components with different metadata, for example:
- A Rust API, a TypeScript frontend, and a Python worker.
- iOS, Android, and web apps in one repository.
Don't enable it for a single application that merely has several directories. For applications that span several repositories, see Multi-Repository Application Commands.
Configure services
-
Add a
[monorepo]table and one[[monorepo.services]]entry per service to.forge/config/project.toml:tomlschema_version = "1.0.0" [project] name = "my-monorepo" description = "Multi-service project" language = "Rust" framework = "axum" testing_framework = "cargo test" package_manager = "cargo" [monorepo] enabled = true [[monorepo.services]] name = "api" path = "services/api" description = "REST API service" language = "Rust" framework = "axum, tokio" testing_framework = "cargo test" package_manager = "cargo" [[monorepo.services]] name = "web" path = "services/web" description = "Frontend web application" language = "TypeScript" framework = "React, Next.js" testing_framework = "Jest" package_manager = "npm" -
Validate the configuration:
bashfrg config validate -
If you use a lockfile, update it with
frg config lock.
Tip:
frg config init --interactiveanalyzes the repository with AI, detects monorepos, and proposes service entries for your approval.
Service fields
| Field | Required | Description |
|---|---|---|
name | Yes | Service identifier. Must be non-empty and unique. |
path | Yes | Directory relative to the repository root. Must exist, stay inside the repository, and be unique. |
description | No | Overrides project.description. |
language | No | Overrides project.language. |
framework | No | Overrides project.framework. |
testing_framework | No | Overrides project.testing_framework. |
package_manager | No | Overrides project.package_manager. |
To turn monorepo mode off, remove the [monorepo] table or set enabled = false.
Select a service
frg config set-service api
Forge stores the selection in .forge/context.toml:
service_name = "api"
Check the current selection:
frg config show-context
The output includes a line such as Service: api (from config file).
The selection persists until you change or clear it:
frg config clear-service
frg config clear-context also clears the service.
How service context works
When a service is selected:
- The prompt includes a
<service>block with the service metadata. Service fields override the matching[project]fields. - The agent is told that it works in a monorepo and that the current work is focused on the selected service.
- Toolchain, agent, and command configuration stay shared across all services.
When no service is selected, Forge uses the project-wide metadata only.
# Work on the API
frg config set-service api
frg code create
# Switch to the frontend
frg config set-service web
frg code create
# Repository-wide work
frg config clear-service
frg docs create
When frg issue split runs with a <service> block in the context, it splits the work by service and names the files issue_<service_slug>.md.
Service placeholders
Custom prompts can reference service metadata with these placeholders:
{{service.name}}{{service.path}}{{service.description}}{{service.language}}{{service.framework}}{{service.testing_framework}}or{{service.testingFramework}}{{service.package_manager}}or{{service.packageManager}}
You are working on the {{service.name}} service in {{service.path}}.
It uses {{service.language}} with {{service.framework}}.
Run tests with {{service.testing_framework}}.
Troubleshooting
Monorepo is enabled but no services are defined. Add [[monorepo.services]] entries or set monorepo.enabled = false
Cause: [monorepo] enabled = true has no service entries.
Solution: Add at least one [[monorepo.services]] entry, or set enabled = false. Then run frg config validate.
Service <name> not found in monorepo configuration.
Cause: frg config set-service received a name that isn't defined. The error lists the available services.
Solution:
- Use one of the listed names. Names must match exactly.
- To add a service, edit
.forge/config/project.toml.
Duplicate service name <name> found in monorepo configuration
Cause: Two services use the same name. The same applies to Duplicate service path '<path>' found in monorepo configuration.
Solution: Give each service a unique name and path.
Service <name> path does not exist:
Cause: The service directory doesn't exist relative to the repository root.
Solution: Correct path, or create the directory.
Service <name> path is outside repository bounds: <path>
Cause: path is absolute or resolves outside the repository.
Solution: Use a relative path inside the repository.
Service name cannot be empty
Cause: A service has name = "".
Solution: Set a name.
Monorepo is not enabled in project configuration.
Cause: You ran frg config set-service, or a service is still selected, but monorepo.enabled is false. If the [monorepo] table is missing, the error is Monorepo is not configured.
Solution:
- Set
monorepo.enabled = truein.forge/config/project.tomland define services. - Or run
frg config clear-service.
The agent uses the wrong language or framework
Cause: A different service, or no service, is selected.
Solution:
- Run
frg config show-contextto check the selection. - Run
frg config set-service <name>. - Check the service entry in
project.toml. Service fields override project fields only when they are set.
Configuration has changed since last lock.
Cause: You edited project.toml after running frg config lock.
Solution: Run frg config validate, then frg config lock.
FAQ
Can services have different toolchains? No. Toolchain configuration is shared by the whole repository.
Can I select several services at once? No. For work that spans services, clear the selection.
Do I need to select a service for every command? No. The selection persists in .forge/context.toml until you change or clear it.