Thanks for your interest in contributing to devbox! This guide covers everything you need to get started.
Requirements: Go 1.24+
git clone https://github.com/junixlabs/devbox.git
cd devbox
go build -o devbox ./cmd/devbox/
go test ./...cmd/devbox/ CLI entry point — all commands in main.go
internal/
config/ devbox.yaml parsing and validation
workspace/ Workspace model, Manager interface, resource limits
ssh/ SSH remote command executor
docker/ Docker Compose management via SSH
tailscale/ Tailscale serve/unserve/status
identity/ User identity resolution (Tailscale login)
server/ Server pool management
port/ Port auto-allocation registry
metrics/ Resource metrics collector
snapshot/ Snapshot & restore workspace state
template/ Workspace templates (built-in + user-defined)
tui/ Interactive TUI dashboard (Bubble Tea)
plugin/ Plugin system (Provider/Hook interfaces)
registry/ Community template registry
ci/ CI/CD integration (GitHub Actions)
errors/ Typed errors with suggestions
ui/ CLI output helpers (spinners, colors)
testutil/ Shared test helpers
integration/ Multi-user E2E tests
- Create a function
yourCmd() *cobra.Commandincmd/devbox/main.go - Wire it:
rootCmd.AddCommand(yourCmd()) - Follow existing patterns — use
RunE(notRun), wrap errors withfmt.Errorf("devbox your-cmd: %w", err)
- Create
internal/yourpkg/yourpkg.go - Define an interface for the contract
- Implement the interface
- Import from CLI in
main.go
- Add to
DevboxConfigstruct ininternal/config/config.gowith ayamltag - Add validation in
Load()if needed - Update
devbox.yaml.example
See docs/PLUGIN_API.md for the full plugin development guide.
Plugins implement plugin.Provider (custom workspace backends) or plugin.Hook (lifecycle callbacks). Create a directory with a plugin.yaml manifest and a Go binary, then install with devbox plugin install <path>.
Templates are YAML files in internal/template/builtin/. To add a new built-in template:
- Create
internal/template/builtin/yourtemplate.yaml - Follow the schema from existing templates (name, image, services, ports)
- Register it in the built-in embed
To share templates via the community registry, use devbox template push.
- Error wrapping: Always use
fmt.Errorf("context: %w", err) - Naming: Go conventions — CamelCase exports, lowercase packages
- Interfaces: Define contracts before implementations
- Tests: Every package should have
_test.gofiles - No runtime dependencies: Single binary, cross-compile friendly
- Fork and create a feature branch
- Make your changes with tests
- Run
go test ./...andgo vet ./... - Submit a PR with a clear description of what and why
By contributing, you agree that your contributions will be licensed under the project's license.