A zero-config dev runner for Go projects
Build, run, watch, test – all from one command.
With a built-in TUI log viewer that has vim keybindings, log level filtering, and JSON pretty-printing.
Most Go dev workflows look like this: go run ., manually restart on every change, no log filtering or search. devr replaces all of that with a single command.
- One command to run –
devr app runbuilds, starts, and opens a log viewer - Auto-restart on changes –
devr app watchrebuilds on every.gofile save - TUI log viewer – search, filter by level, JSON preview, vim navigation
- Pretty test output – dots, compact, or verbose – with failure summaries
- Zero config – works out of the box, optional
.devr.yamlfor customization
go install github.com/pabiadzinski/devr/cmd/devr@latestdevr init myapp && cd myapp
devr app runThat's it. Your app is running and you're in the log viewer.
devr app run # build, start, open log viewer
devr app run --race=false # disable race detector (enabled by default)
devr app run --no-env # skip loading .env file
devr app run --env-file .env.local
devr app watch # same, but auto-restart on .go changes
devr app watch --debounce 1s
devr app stop # send SIGTERM to the background process
devr app attach # reattach to a running process
devr app logs # view logs from last run
devr app ps # list all managed processesCLI flags override .devr.yaml values. Race detector is enabled by default.
devr test run # run tests with compact output
devr test run -f dots # minimal dot output
devr test run -f verbose # full verbose
devr test run -r TestFoo # run specific tests
devr test bench # run benchmarks
devr test cover # coverage report, opens in browser
devr test cover -p custom.outdevr init myapp # creates go.mod, main.go, .gitignoreThe built-in log viewer gives you a full-screen TUI with real-time tailing:
| Key | Action |
|---|---|
j/k, arrows |
Navigate |
Ctrl+D/U |
Half page scroll |
Ctrl+F/B |
Full page scroll |
H/M/L |
Top / middle / bottom of screen |
g / G |
Jump to top / bottom |
/ |
Filter lines (search + hide non-matching) |
s |
Search with highlight (no filtering) |
n / N |
Next / prev search match |
1 2 3 4 |
Filter: error, warn, info, debug |
0 |
Clear filter |
w |
Toggle line wrap (on by default) |
Alt+Enter |
Insert marker line |
Tab |
JSON pretty-print panel |
Enter |
Insert blank line |
y |
Copy line to clipboard |
q |
Detach (process keeps running) |
Ctrl+C x2 |
Stop process & exit |
command devr completion fish | source # fish (add to ~/.config/fish/config.fish)
eval "$(devr completion bash)" # bash (add to ~/.bashrc)
eval "$(devr completion zsh)" # zsh (add to ~/.zshrc)Drop a .devr.yaml in your project root to customize behavior. All fields are optional:
build:
cmd_pattern: "cmd/*/main.go"
race: true # enabled by default, use --race=false to disable
flags: ["-trimpath"] # extra go build flags
run:
env_file: ".env" # or .env.local, etc. (defaults to .env)
no_env: false # skip loading env file
watch:
extensions: [".go"]
exclude: ["vendor", "node_modules"]
debounce: 500ms
logs:
format: auto # auto, json, or text
level_field: level # JSON field or key=value field for level
level_values:
error: ["error", "err", "fatal"]
warn: ["warn", "warning"]
info: ["info"]
debug: ["debug", "trace"]
highlight_fields: ["msg"]
test:
cover_profile: "coverage.out"
notify: true # macOS desktop notifications on build/crash failuresBy default, devr uses logs.format: auto: it first tries JSON logs, then falls back to plain text / key=value parsing. This works out of the box for logs like {"level":"info","msg":"ready"}, INFO server started, or lvl=warning msg="slow query" if you set level_field: lvl.
Without a config file, devr uses sensible defaults – it just works.
MIT
