DevSetup installs complete development environments with one command:
devsetup web
devsetup ai
devsetup mobile
Success = a developer runs this ONCE and it works.
If it fails, nothing else matters.
- Reliability > features
- Simplicity > flexibility
- Working installs > clean abstractions
- Real usage > theoretical design
If a change risks breaking installs → reject it.
- Single responsibility per module
- No OS logic outside installer layer
- Profiles describe intent, not execution
- Prefer config (YAML) over hardcoding
- Fail fast, log clearly, never silently fail
- Default behavior must work without config changes
cmd/devsetup → CLI entry
internal/osdetect → OS + distro detection
internal/installer → package manager abstraction
internal/profiles → profile resolution
internal/config → YAML loader
internal/logger → logging system
plugins/ → user extensions
configs/ → profiles.yaml
scripts/ → install.sh
Flow:
CLI → detect OS → load config → resolve profile → filter installed → install → plugins
Profiles are YAML-driven.
Rules:
- Only widely used tools
- No niche frameworks
- No bloat
- Must work across OS
Bad:
web → 20 tools
Good:
web → git, nodejs, docker
Profiles must remain minimal.
- Use native package managers only:
- apt / dnf / pacman / brew / winget
- Always non-interactive installs
- No hacks unless unavoidable
- Retry on failure (network issues)
Never:
- mix package managers
- run random scripts
Supported:
- Linux (apt, pacman, dnf)
- macOS (brew)
- Windows (winget)
OS detection must be:
- isolated
- testable
- predictable
Unit:
- OS detection
- package manager mapping
- profile resolution
Integration:
- command generation
- dry-run execution
Never run real installs in CI.
- Never execute unknown remote code
- Validate download URLs
- Use official package sources only
install.sh must:
- only download verified binaries
- not execute arbitrary code
- Static Go binaries
- GitHub releases (single source of truth)
- Provide:
- install.sh
- checksums
No release without:
- manual test on Linux + macOS
Plugins are optional shell scripts:
plugins/*.sh
Rules:
- executed AFTER install
- never required for core functionality
- failures must not break main install
- YAML profiles (done)
- user-defined profiles
- remote profiles
- plugin registry
Do NOT implement early.
- Over-engineering before validation
- Adding niche tools to profiles
- Hardcoding OS-specific packages in code
- Silent failures
- Complex CLI UX
DevSetup is NOT:
- a package manager
- a framework installer
- a dev environment manager
It is:
→ A thin orchestration layer over system package managers
If complexity grows, you are doing it wrong.
Goal: prove usefulness
Features:
- OS detection
- one profile (web)
- apt + brew only
- direct package install
No:
- YAML
- plugins
- retries
Success condition: → Works on 3 real machines without failure
Add:
- YAML profiles
- multiple profiles (web, ai)
- basic logging
- dry-run
Still NO:
- plugins
- version pinning
Focus: → correctness across OS
Add:
- retry logic
- package existence check
- better error handling
Focus: → zero-failure installs
Add:
- plugin system
- user config override
Only AFTER stability is proven
Add:
- install.sh
- GitHub releases
- Homebrew + winget
Ignore apt/dnf initially (high friction)
Add:
- docs
- demo GIF
- community feedback
- bug fixes
NOT features.