Recipe: monorepo with frontend / backend / devops roles¶
Problem¶
Your monorepo houses a React frontend, a Go API, and a Kubernetes deployment manifest. Every contributor runs jarvy setup, but you don't want frontend devs installing kubectl and helm, and you don't want platform engineers waiting through a pnpm install of 800 packages they'll never use.
Config¶
jarvy.toml
role = "frontend" # default for fresh checkouts
[roles.base]
description = "Tools every contributor needs"
tools = ["git", "docker", "make"]
[roles.frontend]
description = "React frontend developers"
extends = "base"
tools = ["node", "pnpm"]
[roles.frontend.tools]
node = "20"
[roles.backend]
description = "Go API developers"
extends = "base"
tools = ["go", "golangci-lint", "air", "psql"]
[roles.backend.tools]
go = "1.22"
[roles.devops]
description = "Platform / infrastructure"
extends = "base"
tools = ["kubectl", "helm", "terraform", "kustomize", "stern"]
[roles.fullstack]
description = "People who do both"
extends = "frontend"
tools = ["go", "golangci-lint"]
# Hooks scoped per-role
[hooks.frontend.node]
post_install = "pnpm install"
[hooks.backend.go]
post_install = "go mod download"
[commands]
dev = "make dev"
test = "make test"
build = "make build"
Why it works¶
| Pattern | Effect |
|---|---|
role = "frontend" at top |
Default for new checkouts — no env vars, no shell config |
extends = "base" |
Each role automatically gets git, docker, make |
[roles.frontend.tools] override |
Pins node to 20 just for frontend devs |
extends = "frontend" on fullstack |
Inheritance chains cleanly; up to 5 levels deep |
[hooks.<role>.<tool>] |
Hook only fires if that role's pulling in that tool |
Each contributor either:
- Sticks with the default (
jarvy setup) - Switches per-run (
jarvy setup --role devops) - Sets a per-checkout override (commit a different
role = ...to a personal branch... but that's smelly — better to use--role)
Variations¶
Multiple roles for "I do everything" people:
Last entry wins for conflicts.
Optional roles (opt-in, never default):
Don't set a default role. Each contributor must use --role <name>. Stricter, but no implicit toolchain.
Roles for different OSes:
Run on macOS only: jarvy setup --role frontend --role macos-extras.
Inspecting what a role would install:
jarvy roles show frontend --resolved # full tool list including inherited
jarvy roles show frontend --inheritance # the extends chain
jarvy roles diff frontend backend # what changes between two roles
Caveats¶
- Roles aren't environments.
[env.vars]is global — same env for every role. If you need per-role env, use apre_setuphook that branches on$JARVY_ROLE. - Don't over-engineer. If your team is six people and everyone needs the same tools, skip roles entirely. A flat
[provisioner]is simpler and reads better. - CI uses one role. Pick one for your default CI matrix (typically
baseor whichever role your CI runs against), and add a separate matrix entry per role you want to test.
See also¶
- Roles guide — full TOML reference
- Roles & inheritance concept — precedence rules and resolution model