Documentation previewThese docs are actively being built. Some pages may change as the framework and examples are finalized.
Skip to content

Project Structure

A GoForj Project is a Go module with generated app composition, shared application code, configuration, and runtime support.

Most Projects start with one app: the default app named app.

Common Layout

text
.
|-- .goforj.yml
|-- .env
|-- go.mod
|-- cmd/
|   `-- app/
|       `-- main.go
|-- app/
|   |-- commands.go
|   |-- lifecycle.go
|   |-- routes.go
|   |-- schedules.go
|   `-- wire/
|-- internal/
|-- migrations/
`-- bin/

Some files appear only when their component is enabled.

The Rule

internal/ owns behavior. app/ owns exposure.

Put services, repositories, controllers, jobs, subscribers, and domain behavior under internal/. Use app composition files to decide which behavior is exposed by a runnable app.

.goforj.yml

.goforj.yml is the Project contract for rendering and local development.

It records:

  • project name
  • Go module path
  • selected project components
  • optional starter kit
  • App dev lifecycles and independent custom watches
  • optional local module replacements
  • per-app component metadata under apps when named apps exist

App discovery is layout-based. A named app exists when its conventional files exist under cmd/<app> and app/<app>.

cmd/app

cmd/app/main.go is the default app binary entrypoint.

It should stay small. It starts the generated command surface for the app; it should not own routes, jobs, services, provider sets, or business workflows.

Named apps use the same pattern:

text
cmd/marketplace/main.go

app

app/ is the default app composition layer.

Common files include:

  • app/commands.go
  • app/lifecycle.go
  • app/routes.go
  • app/schedules.go
  • app/wire/...

Named apps compose through app/<name>/:

text
app/marketplace/routes.go
app/marketplace/wire/

internal

internal/ contains shared application behavior and generated runtime support.

Runtime support packages include:

  • internal/runtime for lifecycle machinery, timeouts, discovery, and generated app metadata
  • internal/http for HTTP runtime behavior
  • internal/jobs for worker runtime behavior
  • internal/schedules for scheduler runtime behavior
  • internal/metrics and internal/observability for runtime visibility

Resource packages appear only when their components are enabled:

  • internal/database for a selected database engine
  • internal/caches for Cache
  • internal/events for Events
  • internal/storages for File Storage
  • internal/queues and internal/jobs for Background Jobs
  • internal/mail for Mail

Application-owned packages can be organized by domain:

text
internal/users
internal/checkout
internal/reports

internal/runtime/apps.go

internal/runtime/apps.go is generated by GoForj. Do not edit it by hand.

It compiles the app list and deterministic runtime defaults into binaries so production runs do not depend on .goforj.yml or source directory scanning.

Frontend Files

When Web UI is enabled, frontend source and embedded build output live next to the app binary:

text
cmd/app/frontend/
cmd/marketplace/frontend/

This keeps each app's embedded assets local to the binary that serves them.

Extension Points

Prefer these files before editing generated runtime glue:

  • lifecycle hooks in app/lifecycle.go
  • routes in app/routes.go
  • commands in app/commands.go
  • schedules in app/schedules.go
  • providers in app/wire/...
  • named app equivalents under app/<name>/

Next Steps