Lightweight full-stack Golang boilerplate
Build apps in Go the light, clean and fast way. Gin, Vue 3 and strict rules under which people and AI write equally good code.
Clone the repo and let AI do the work
What Gin GoKick does
1–5
Getting started
-
1
Go and Gin
One binary of 27 MB serves the templates and the frontend build.
-
2
Config from .env
Variables are checked. A typo stops the start, not production.
-
3
Rules in AGENTS.md
People and AI write by the same rules, and tools enforce them.
-
4
Pre-commit gate
One block runs the lint, types and tests of CI before a commit.
-
5
Pre-push hook
Lefthook checks the branch name and commit messages before a push.
6–10
Database
-
6
PostgreSQL 18
The app connects through pgx, one command starts the database.
-
7
goose migrations
They run at start under a lock, so instances never collide.
-
8
sqlc instead of an ORM
You write SQL, and typed Go functions are generated from it.
-
9
Tests with a database
Each test gets an empty migrated schema, in CI and locally.
-
10
Queries by function
Spans and metrics name each query by the function of the app that ran it.
11–14
Deployment
-
11
Docker image
The image runs on Alpine without root and checks the database.
-
12
Deploy guide
Guides the first deploy to Docker Swarm with Cloudflare and Grafana.
-
13
Graceful restart
On shutdown, requests in progress finish within five seconds.
-
14
Emails over SMTP
Mailpit catches them locally, Amazon SES sends them live.
15–18
Frontend
-
15
Vite the Laravel way
HMR runs through Go, so development gets the production CSP.
-
16
Vue 3 and Tailwind 4
The SPA with vue-router and the Go pages share one style.
-
17
Go types and guards
tsgen writes types and guards, so API changes fail to compile.
-
18
Routes by sign-in
Every route says who may open it, and tabs share the sign-in.
19–21
Go templates
-
19
SSR with html/template
The server renders the home page, the 404 and the app entry in each language.
-
20
Guarded templates
Checks catch missing files, untranslated text and unknown keys in templates.
-
21
Mail templates
Mails come from Go templates and reach users in their own language.
22–25
Components
-
22
Shared elements
Icons, dropdowns and tooltips look the same in Vue and Go.
-
23
Data grid
The URL keeps the filters, and a selection runs bulk actions.
-
24
Forms
Text and number fields show the API error right below them.
-
25
Toasts and dialogs
Toasts survive navigation, and a modal confirms risky actions.
26–29
Languages and SEO
-
26
Languages in the URL
Languages live in the URL with hreflang, accounts keep theirs.
-
27
Translation checks
tools/i18n catches missing keys, unused texts and bad plurals.
-
28
ICU in Go and Vue
Plurals and numbers look the same in Go and in the browser.
-
29
Titles and sharing
A missing title, description or share image fails the checks.
30–34
Security
-
30
Sign-in
Passwords use argon2id, the attempt limit spans all instances.
-
31
Signed-in devices
Users see every device with its last IP and can sign it out.
-
32
CSP with a nonce
A nonce and Trusted Types keep injected scripts from running.
-
33
CSRF without tokens
http.CrossOriginProtection refuses requests from other sites.
-
34
A+ headers
HSTS, COOP, CORP and Permissions-Policy come from the server.
35–40
Observability
-
35
GlitchTip for Go and Vue
Links browser errors to the backend, releases are commit SHAs.
-
36
One trace ID
The log, the span, GlitchTip and X-Trace-Id carry it, even with telemetry off.
-
37
Metrics over OTLP
Requests, queries, the pool and the Go runtime leave with the traces.
-
38
JSON logs in Loki
trace_id and user_id, never an email, go to stdout and on to Loki.
-
39
Seven Grafana boards
From availability and the SLO to slow queries and their traces.
-
40
Business events
One call writes the log, the count and the span event, without personal data.
41–44
Analytics and consent
-
41
Cookie banner
Refusing is as easy as accepting, and the choice can change any time.
-
42
Analytics and conversions
GA4, Ads and Meta measure and count conversions only after consent.
-
43
Hashed email
Only Ads and Meta get the email, and only as SHA-256.
-
44
Events from Go
Go defines the events, and typecheck lets none go unmapped.