Help us shape the future of Go! Take the 2026 Go Developer Survey

kit

module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2026 License: MIT

README

kit

Small, reusable Go building blocks I use across my SaaS apps (server-rendered Go + Datastar, PostgreSQL, SumUp billing).

It's public and MIT-licensed — if it's useful to you, take it. But it exists for my own apps: no support, no stability guarantees, no roadmap, breaking changes whenever I need them. Pin a commit if you depend on it.

Packages

Package What it does Status
auth Session-based auth: bcrypt password hash/verify, random tokens, and a cookie-backed session Manager + middleware. You implement SessionStore; sessions key off an opaque user id. early
tenancy Resolve the current tenant from a request — custom domain → subdomain — onto the context, with middleware. You implement the Lookup. early
csrf Same-origin CSRF protection as net/http middleware — no tokens, no session storage, no template changes. Unsafe methods carrying a browser Origin/Referer must match the request's own Host, so subdomains and custom domains work with no allowlist; requests with neither header (signature-verified webhooks, curl) pass through. Pairs with a SameSite=Lax session cookie. early
authz Tiny generic role→permission core (Roles[R].Can/CanAny/CanAll). Resource-scoped rules stay in your app and compose with a permission check. early
migrate Dependency-light SQL migration runner over an fs.FS of *.up.sql files — Rails' db:migrate, DB-only. early
jobs Postgres-backed background job queue + worker (FOR UPDATE SKIP LOCKED, retries w/ backoff, lease-based crash recovery) — Rails' Solid Queue, no Redis. Run-later scheduling, priorities, deduplicated enqueue (WithUnique) and self-rescheduling periodic jobs (RegisterPeriodic) for cron-free recurring work. early
cache Postgres-backed key/value cache with TTL — Rails' Solid Cache, no Redis. early
log Structured request/job logging on log/slog: a process logger plus context propagation (request_id/user_id/tenant_id/job_id) and net/http middleware that stamps a request id and logs one line per request. Keeps the SSE Flusher passthrough Datastar needs. early
mail Tiny SMTP sender for transactional email: one Send(to, subject, body), PLAIN auth, graceful-disable when no host is set (returns ErrDisabled so callers can fall back to e.g. a copyable link). early
money Money as integer minor units: precise decimal-string Cents parsing (no float rounding, half-up), Decimal for input values, and symbol+separator Format for display. One place to turn "1234.56" into 123456 and back. early
i18n Message-catalog engine: a Bundle loads flattened key→string JSON catalogs from any fs.FS, with default-locale + key fallback, Resolve (param/cookie/Accept-Language), %{name} interpolation, and context plumbing (WithLocale/FromContext). HTTP policy stays in your app. early
dbx The small repetitive helpers for building sqlc/pgx params from Go values: UUID/NullUUID/Date/Timestamptz pgtype wrappers and generic Ptr/Deref/DerefOr for nullable columns. early
billing/sumup Recurring-subscription + saved-card (merchant-initiated) billing orchestration on top of the official sumup/sumup-go SDK — the bit the SDK deliberately doesn't do. SDK-free core: recurring Engine (you implement Charger/Store), Interval cadences (weekly→yearly) and VerifyWebhook (HMAC-SHA256). billing/sumup/sumupgo is the SDK-backed side: a Charger plus a Client for the GA saved-card flow — create a customer, open a CHECKOUT/SETUP_RECURRING_PAYMENT checkout for the card widget or hosted page, read back the tokenized card, list/delete saved cards. early
billing/stripe Thin, storage-free wrapper over the Stripe API for subscription billing: CheckoutURL (hosted Checkout Session — cards/3DS/promo codes), PortalURL (Customer Portal), EnsureCustomer, SessionSubscription/CustomerSubscription (sync on the checkout/portal return without waiting on the webhook), and VerifyWebhook. Stripe owns renewals + discounts (coupons); you map your plan keys to price ids and persist subscription state. early
env Tiny zero-dependency .env loader: Load(path) reads KEY=VALUE into the process environment without overriding already-set vars (so the real env / systemd always wins). No config struct, no coercion — pair it with your own config over os.Getenv. early
datastarx Minimal Server-Sent-Events helpers for driving Datastar responses from net/http. early
storage Thin S3-compatible object-store wrapper (Cloudflare R2 / AWS S3 / MinIO): put, get, delete, presigned GET/PUT URLs. Built on aws-sdk-go-v2 with the checksum fix R2 needs. early

Dependency weight: billing/sumup/sumupgo pulls in sumup-go and storage pulls in aws-sdk-go-v2. They live behind their own import paths, so the Go build only compiles what you import — but as one module they all share go.sum. If that bloat ever matters, the heavy adapters can move to their own modules later.

Design notes

  • Thin, not a framework. Each package fills a specific gap and stays out of your way. billing/sumup is orchestration over the official SDK, not another API client; datastarx is SSE plumbing, not a full Datastar wrapper.
  • Decoupled via interfaces. Nothing here hard-binds your database or HTTP router — you implement small interfaces (Store, Charger, …) and the kit drives the workflow.

Install

go get github.com/a3yko/kit@latest

License

MIT.

Directories

Path Synopsis
Package auth provides reusable building blocks for session-based authentication: password hashing, cryptographically-random tokens, and a cookie-backed session manager with middleware.
Package auth provides reusable building blocks for session-based authentication: password hashing, cryptographically-random tokens, and a cookie-backed session manager with middleware.
Package authz is a tiny role-based authorization core: declare which permissions each role grants, then ask whether a role has a permission.
Package authz is a tiny role-based authorization core: declare which permissions each role grants, then ask whether a role has a permission.
billing
stripe
Package stripe is a thin, decoupled wrapper over the Stripe API for subscription billing: start a hosted Checkout Session (cards, 3DS, promo codes), open the Customer Portal (change plan/card, cancel, invoices), verify webhooks, and look up a checkout session's or a customer's subscription so you can sync state immediately instead of waiting on the async webhook.
Package stripe is a thin, decoupled wrapper over the Stripe API for subscription billing: start a hosted Checkout Session (cards, 3DS, promo codes), open the Customer Portal (change plan/card, cancel, invoices), verify webhooks, and look up a checkout session's or a customer's subscription so you can sync state immediately instead of waiting on the async webhook.
sumup
Package sumup provides recurring-subscription and saved-card (merchant-initiated) billing orchestration on top of SumUp.
Package sumup provides recurring-subscription and saved-card (merchant-initiated) billing orchestration on top of SumUp.
sumup/sumupgo
Package sumupgo is an example billing/sumup.Charger backed by the official SumUp Go SDK (github.com/sumup/sumup-go).
Package sumupgo is an example billing/sumup.Charger backed by the official SumUp Go SDK (github.com/sumup/sumup-go).
Package cache is a Postgres-backed key/value cache — Rails' Solid Cache, no Redis.
Package cache is a Postgres-backed key/value cache — Rails' Solid Cache, no Redis.
Package csrf protects state-changing requests by checking that they were sent from the same origin they are addressed to — no hidden form tokens, no session storage, no template changes.
Package csrf protects state-changing requests by checking that they were sent from the same origin they are addressed to — no hidden form tokens, no session storage, no template changes.
Package datastarx contains small helpers for driving [Datastar] responses over Server-Sent Events from net/http.
Package datastarx contains small helpers for driving [Datastar] responses over Server-Sent Events from net/http.
Package dbx holds the small, repetitive helpers you reach for when building sqlc/pgx query params from ordinary Go values: wrapping a uuid/time in the pgtype the generated code wants, and converting between "" / zero and a nullable pointer.
Package dbx holds the small, repetitive helpers you reach for when building sqlc/pgx query params from ordinary Go values: wrapping a uuid/time in the pgtype the generated code wants, and converting between "" / zero and a nullable pointer.
Package enum makes a closed set of string values unforgeable.
Package enum makes a closed set of string values unforgeable.
Package env is a tiny, zero-dependency .env loader.
Package env is a tiny, zero-dependency .env loader.
Package fail removes the `if err != nil` noise from linear code, without removing the error handling.
Package fail removes the `if err != nil` noise from linear code, without removing the error handling.
Package i18n is a tiny message-catalog engine with per-request locale on the context.
Package i18n is a tiny message-catalog engine with per-request locale on the context.
Package jobs is a Postgres-backed background job queue — Rails' Solid Queue, no Redis.
Package jobs is a Postgres-backed background job queue — Rails' Solid Queue, no Redis.
Package log is structured request/job logging on top of log/slog: a process logger plus context propagation so every line a request (or background job) emits carries the same request_id, user_id, tenant_id and job_id without threading them through every call.
Package log is structured request/job logging on top of log/slog: a process logger plus context propagation so every line a request (or background job) emits carries the same request_id, user_id, tenant_id and job_id without threading them through every call.
Package mail sends transactional email over SMTP.
Package mail sends transactional email over SMTP.
Package migrate is a tiny, dependency-light SQL migration runner — Rails' db:migrate, DB-only.
Package migrate is a tiny, dependency-light SQL migration runner — Rails' db:migrate, DB-only.
Package money formats and parses amounts held as integer minor units (cents).
Package money formats and parses amounts held as integer minor units (cents).
Package opt is OCaml's `'a option` in Go.
Package opt is OCaml's `'a option` in Go.
Package storage is a thin wrapper over an S3-compatible object store (Cloudflare R2, AWS S3, MinIO, …) for the handful of operations an app actually needs: put, get, delete, and presigned URLs.
Package storage is a thin wrapper over an S3-compatible object store (Cloudflare R2, AWS S3, MinIO, …) for the handful of operations an app actually needs: put, get, delete, and presigned URLs.
Package tenancy resolves the current tenant from an HTTP request — a subdomain of your apex via BySubdomain, any other host via ByCustomDomain — and carries it on the request context.
Package tenancy resolves the current tenant from an HTTP request — a subdomain of your apex via BySubdomain, any other host via ByCustomDomain — and carries it on the request context.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL