shelf started as a hands-on project for learning idiomatic Go, Cobra, and clean CLI architecture — and grew into a genuinely useful way to stop losing links in browser tabs.
| Language | Go |
| CLI framework | Cobra |
| Database | SQLite via modernc.org/sqlite (pure Go, no CGO) |
| Architecture | Repository pattern, one repository per domain entity |
Rather than one monolithic repository handling every table, CollectionRepository and LinkRepository each own their table's persistence logic. The dependency between them is explicit in the constructor signature, not implicit in duplicated SQL.
Every command uses RunE instead of Run, returning wrapped errors up through the root command's Execute() and back to main — the single place that prints the final error and exits.
Every write operation checks its result. A rename or delete affecting zero rows returns a wrapped not-found error instead of exiting quietly as if it succeeded.
shelf-cli/ ├── main.go # wiring: db connection, migrations, repo + command setup ├── cmd/ # Cobra command definitions │ ├── root.go │ ├── collection.go │ └── link.go ├── internal/ │ ├── db/ # connection + migrations │ ├── store/ # data access layer │ │ ├── errors.go # shared sentinel errors (ErrNotFound) │ │ ├── collection.go # CollectionRepository │ │ └── link.go # LinkRepository │ └── ui/ # terminal output styling & rendering └── go.mod
“Built as a learning project for backend and systems-focused Go development — CLI design, package architecture, and idiomatic error handling.”
— Biplob, author of shelf
View source on GitHubMIT Licensed