App
A GoForj Project can contain one or more apps. An app is the runnable boundary: it has a binary, command surface, composition files, and runtime defaults.
Most Projects have one app. That default app is named app.
Default App
The default app uses the simplest layout:
cmd/app/main.go
app/
app/wire/cmd/app/main.go is the binary entrypoint. It stays small.
app/ owns composition: routes, commands, schedules, lifecycle hooks, and app-level exposure.
app/wire/ owns the Wire graph for that app.
Application behavior still belongs under internal/.
Named Apps
Larger Projects can add named apps:
cmd/marketplace/main.go
app/marketplace/
app/marketplace/wire/Use named apps when the Project needs another runnable boundary, such as a marketplace app, backstage app, or admin app. Do not add a named app just to organize packages. Normal application code still belongs in internal/.
App versus Runtime
An app can expose multiple runtimes:
- HTTP
- jobs
- scheduler
- CLI commands
For example, the marketplace app can run:
forj marketplace api
forj marketplace worker
forj marketplace schedulerThe app is the boundary. The runtime is the process role running inside that boundary.
The same app prefix also applies to generated commands and app-aware native commands:
forj marketplace route:list
forj marketplace make:controller checkout
forj marketplace buildApp versus Project
Use this distinction when deciding where code belongs:
| Concern | Belongs In |
|---|---|
| Project configuration and selected components | .goforj.yml |
| App composition | app/ or app/<name>/ |
| App Wire graph | app/wire/ or app/<name>/wire/ |
| Binary entrypoint | cmd/app/ or cmd/<name>/ |
| Business behavior | internal/... |
| Reusable runtime machinery | internal/runtime, internal/http, internal/jobs, internal/schedules |
If rerendering should preserve a behavior change for all future Projects, the durable fix belongs in GoForj templates or generators. If the behavior is application-specific, it belongs in the generated Project.
Extension Points
Common app-owned extension points include:
app/lifecycle.gofor startup and shutdown hooksapp/routes.gofor route exposureapp/commands.gofor command exposureapp/schedules.gofor schedule exposureapp/wire/...for app-local provider registration
Named apps use the same files under app/<name>/.
Common Mistakes
Common mistakes
- Do not put business workflows in
cmd/<app>,app/, orinternal/runtime. - Do not create a named app when a package under
internal/is enough. - Do not describe named apps as separate modules or microservices by default.
- Do not bypass app composition files with package globals.
Next Steps
- Apps explains the multi-app model.
- Runtime Lifecycle explains startup and shutdown.
- Dependency Injection explains app-local Wire graphs.
