-
Notifications
You must be signed in to change notification settings - Fork 68
Contributing
New here and want to land a change? This page gets you oriented. The canonical,
always-up-to-date rules live in
CONTRIBUTING.md
in the repo — this wiki page is the friendly on-ramp and a FAQ for the questions
that come up most on Discord.
-
Set up. Install Go 1.25+ and Node 22+, then:
git clone https://github.com/vavallee/bindery && cd bindery make dev # backend on :8787 make web-dev # frontend dev server (separate terminal, hot reload)
First run creates
./bindery.dband prompts you to create an admin account. -
Find something to work on. Browse
good first issueandhelp wanted. Comment on the issue so two people don't duplicate work. For anything large, open an issue first to confirm scope before writing code. -
Understand the shape. Bindery is one Go binary with the React UI embedded — no separate API server, no external database, one SQLite file. The Architecture doc maps every package. Backend lives in
internal/andcmd/; the UI inweb/. -
Make the change, then run the checks locally:
make check
This runs exactly what the gating CI runs (build, vet, golangci-lint,
go test -race, and the web typecheck/lint/build/test). If it's green, CI will be too. -
Open the PR. Fork, branch off
main, fill in the template, link the issue (Closes #NN), and add a changelog fragment instead of editingCHANGELOG.md.
Pick a small, self-contained package: internal/opds, internal/textutil,
internal/decision, or a single component in web/src/components/. Avoid the
biggest/most-active files (internal/importer/scanner.go, internal/api/,
web/src/api/) for a first PR — they're large and frequently mid-refactor, so
you can collide with in-flight work. Ask in the issue first if you want to touch
them.
Probably not. Bindery runs a large security suite (CodeQL, Semgrep, gosec, Grype, Checkov, Hadolint, gitleaks, ZAP DAST, SBOM, Scorecard) and most of it is advisory. Only three checks are required to merge:
-
lint (
golangci-lint+go vet+ frontend lint/typecheck) -
validate (Go) (
go test+ race detector) - Security Summary
A red Container Scan is very often a CVE in the base image, unrelated to your change. If a non-required check is red, say so in the PR and a maintainer will confirm whether it's pre-existing.
Run make check (not just go test) — it mirrors CI exactly, including the race
detector, the pinned golangci-lint version, and the full web pipeline. Install
the pinned linter with
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4.
Additive SQL files in internal/db/migrations/, named NNN_description.sql,
applied at startup. Use the next free number. The gap at 010 is intentional
— don't fill it. Two files sharing a number are rejected at boot, so if your
branch and main both added 0NN, renumber yours when you rebase. Migrations are
forward-only and must not destructively rewrite existing rows.
Don't edit CHANGELOG.md — that file is a constant merge-conflict source. Drop a
small fragment in
changelog.d/
instead (one per PR; format in its README.md). Preview with make changelog. A
maintainer assembles fragments into the changelog at release time.
Bindery is intentionally a download manager — it acquires, organizes, and serves books (OPDS/Calibre). It deliberately does not track read/unread, reading progress, ratings, or shelves (that's a library manager's job — use Hardcover or Audiobookshelf). Integrations that hand books off to other tools are in scope; re-implementing another tool's job is not. When in doubt, ask on Discord or open an issue before building.
Use the issue templates. Real-time help is on Discord, but file a GitHub issue for anything you want tracked so it isn't lost in chat. Never post security vulnerabilities publicly — open a private advisory.
This is a small-maintainer project with a fast release cadence. Keep PRs focused and narrow — small, well-tested diffs get reviewed and merged quickest. "Allow edits from maintainers" stays on by default, so a maintainer may push a small fixup to your branch rather than round-tripping review comments.
Yes. The UI follows a documented dark-mode + component convention; every
user-facing string goes through i18n (t()), and new keys go in
web/src/i18n/locales. Docs live in docs/ (deployment/architecture) and this
wiki (recipes/how-tos). Doc-only PRs skip the heavy CI and are very welcome.
See also: Quickstart · Troubleshooting ·
CONTRIBUTING.md
· CODE_OF_CONDUCT.md
Getting started
Setup guides
How-to guides — proxy auth (v1.0)
How-to guides — OIDC (v1.0)
- Google Sign-In
- GitHub OAuth via Dex
- Authelia as OIDC provider
- Authentik
- Keycloak
- Rotate OIDC client secrets
- Recover from broken OIDC
How-to guides — multi-user (v1.0)
Reference
Contributing