No description
  • Go 76.1%
  • Go Template 16.1%
  • TypeScript 4%
  • CSS 1.6%
  • Vue 1%
  • Other 1.2%
Find a file
2026-07-09 19:25:10 +00:00
.github/workflows ci: reference goreleaser-action by full URL 2026-07-09 21:15:09 +02:00
app Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
assets/brand Bootstrap Serval: module, CI, lint, brand assets 2026-07-04 22:16:17 +02:00
auth Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
cache Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
cmd/serval Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
config Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
database Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
examples/demo Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
internal Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
log Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
queue Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
router Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
schedule Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
session Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
.gitignore Bootstrap Serval: module, CI, lint, brand assets 2026-07-04 22:16:17 +02:00
.golangci.yml Bootstrap Serval: module, CI, lint, brand assets 2026-07-04 22:16:17 +02:00
.goreleaser.yaml fix: publish releases to the Forgejo instance, not github.com 2026-07-09 21:22:56 +02:00
.releaserc.yaml ci: release from main via semantic-release and GoReleaser 2026-07-09 21:07:35 +02:00
AGENTS.md Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
CHANGELOG.md chore(release): 0.2.1 [skip ci] 2026-07-09 19:25:10 +00:00
CLAUDE.md Agent guides: AGENTS.md for the framework repo, Copilot coverage for apps 2026-07-05 20:06:34 +02:00
go.mod Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
go.sum Type-safe TypeScript clients: OpenAPI 3.1 from typed routes + Hey API 2026-07-05 14:47:23 +02:00
install.sh feat: curl-based install script 2026-07-09 21:11:40 +02:00
Makefile Move Serval module to git.gasi.dev 2026-07-09 20:27:21 +02:00
README.md feat: curl-based install script 2026-07-09 21:11:40 +02:00
serval.go Kernel + HTTP core: config, log, app, router 2026-07-04 22:25:10 +02:00
serval_test.go Bootstrap Serval: module, CI, lint, brand assets 2026-07-04 22:16:17 +02:00

Serval

Serval logo

The batteries-included Go framework. One command to a working app with queues, cache, scheduling, sessions, auth, and typed TypeScript clients already wired — all of it idiomatic Go: chi routing, SQL-first sqlc queries, explicit DI via samber/do, errors as values rendered as RFC 9457 problem+json.

Part of the Caracal family: apps compile to a single static binary that deploys naturally onto Caracal Serve.

Install

curl -fsSL https://git.gasi.dev/caracal/serval/raw/branch/main/install.sh | bash

Detects your platform, verifies the release checksum, and installs to /usr/local/bin (override with SERVAL_INSTALL_DIR, pin a version with SERVAL_VERSION=v0.2.0). Alternatively: go install git.gasi.dev/caracal/serval/cmd/serval@latest. Once installed, serval upgrade updates in place.

One command

serval new shop        # interactive: API-only or full-stack, drivers, auth, UI kit
cd shop && serval dev --worker --scheduler

Fully scriptable — prompts auto-skip when stdin is not a terminal:

serval new billing --module=git.gasi.dev/acme/billing \
    --auth=self --frontend=tanstack --ui=base --pm=bun --skills --git

The app binary is its own CLI

./shop serve            # HTTP server (graceful shutdown, /healthz + /readyz probes)
./shop migrate          # app migrations + framework schemas, embedded in the binary
./shop queue:work       # background workers
./shop schedule:run     # recurring tasks (pg advisory-lock leader election)
./shop routes           # route table
./shop openapi          # OpenAPI 3.1 from the typed routes (boots with zero config)
./shop key:generate | health | version

One distroless image runs every role — different argv per process type.

Batteries

Subsystem Drivers Notes
Queue River (Postgres) · asynq (Redis) · Cloudflare Queues River: EnqueueTx commits jobs atomically with your data
Cache hot (in-memory) · Postgres · Redis cache.Remember[T] with singleflight dedup
Sessions Postgres · Redis HMAC-signed cookies, tokens hashed at rest
Auth self-hosted (argon2id + API tokens) · Clerk both yield the same auth.Principal
Scheduler built-in Cron/Every, WithoutOverlap, OnOneServer

Every driver passes one shared conformance suite; swap with a .env flip.

Typed handlers → typed TypeScript clients

func (h *Users) Create(ctx context.Context, in CreateUserInput) (router.Created[db.User], error)

Binding (json/path/query/header tags), validation, and problem+json errors are framework concerns. The same signature drives the API contract:

serval client   # routes → openapi.json (committed) → Hey API → frontend/src/client

Rename a Go field and the TypeScript build breaks — at compile time, not in production.

Frontends

--frontend=tanstack (React 19, TanStack Start, Vite 7) or --frontend=nuxt (Nuxt 4), both with Tailwind v4 and a dev proxy into the Go API. Pick the UI kit:

  • shadcn (default, both) — pre-styled components, npx shadcn add
  • Base UI (TanStack) — headless React primitives
  • Nuxt UI (Nuxt) — 125+ official components

serval dev supervises Go rebuilds, sqlc generate on query changes, and the frontend dev server (bun/pnpm/npm — your choice) in one prefixed log stream.

Inner loop

serval generate handler Orders   # + the one registration line to paste
serval generate query orders     # write SQL, then: serval sqlc
serval generate migration add_orders
serval generate job SendReceipt
serval dev                       # hot reload everything

Generators only create files — your code is never rewritten. --skills scaffolds AGENTS.md + .claude/skills/ so AI coding agents know all of these conventions too.

Development (this repo)

make lint test build             # local gate
make test-integration            # needs DATABASE_URL / REDIS_URL
make e2e                         # generate → build → migrate → serve → assert

Requires the latest Go release (1.26+).