Skip to content
Projects

velocitykode/velocity has 38 GitHub stars and 0 forks. GitHot measured 0 in 7 days. Last checked 2026-11-09 19:48 UTC. Last push 2026-10-21.

How these counts are measured

A full-stack Go web framework: React or Vue through Inertia and Vite, plus routing, ORM, auth, queues, scheduler, validation, gRPC, mail, storage, events, and more

Measured star growth

in 24h
Update delayed
in 7 days
0
in 15 days
Update delayed
in 1 month
Update delayed

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

README.md

Original

Velocity

Full-stack Go framework.

Everything you need to build, ship, and run web applications — routing, ORM, authentication, cache, queues, mail, storage, real-time, and more. One binary. No external runtime. No Docker required for development.

Requires Go 1.26+.

Status: Pre-1.0. API is still in flux — breaking changes may occur between minor releases. See RELEASES.md for the versioning policy and CHANGELOG.md for per-release breaking-change notes.

Get Started

brew install --cask velocitykode/tap/velocity
velocity new myapp --stack=react && cd myapp && vel serve

Or add to an existing project:

go get github.com/velocitykode/velocity@latest
package main

import (
    "log"

    "github.com/velocitykode/velocity"
    "github.com/velocitykode/velocity/router"
)

func main() {
    v, err := velocity.New()
    if err != nil {
        log.Fatal(err)
    }

    v.Router.Get("/", func(c *router.Context) error {
        return c.JSON(200, map[string]string{"hello": "world"})
    })

    if err := v.Serve(); err != nil {
        log.Fatal(err)
    }
}

Or just one package

Every subsystem is an importable subpackage. Pull in only what you need: you own the lifecycle, and you compile only what you import.

import "github.com/velocitykode/velocity/cache"

mgr := cache.NewManager(&cache.Config{
    Default: "memory",
    Stores:  map[string]cache.StoreConfig{"memory": {Driver: cache.DriverMemory}},
})

mgr.Put("greeting", "hello", 5*time.Minute)
v, _ := mgr.Get("greeting") // "hello"

See Standalone packages.

For larger apps, declare bootstrap concerns up-front and chain them. The callbacks below live in your own app and routes packages — velocity new scaffolds them for you, or you can write them by hand.

func main() {
    v, _ := velocity.New()

    if err := v.
        Middleware(app.Middleware(v)).      // your global/web/API middleware stacks
        Routes(routes.Register).            // your route definitions
        Events(app.Events(v.Log)).          // your event listeners
        Schedule(schedule.Configure).       // your scheduled jobs
        Errors(app.Errors).                 // optional: add rules to the error handler
        Run(); err != nil {                 // serves HTTP, or runs a `./vel ...` command
        log.Fatal(err)
    }
}

Quick Example

User signs up, validation runs, the user is saved, a job goes onto the queue, and a typed JSON response comes back — all in one handler:

v.Router.Post("/signup", func(c *router.Context) error {
    ctx := c.Request.Context()

    if err := c.Validate(validation.Rules{
        "email": {validation.Required(), validation.Email()},
        "name":  {validation.Required()},
    }); err != nil {
        return err // the error pipeline answers: 422 problem+json, or flash and redirect back
    }

    var input struct {
        Email string `json:"email"`
        Name  string `json:"name"`
    }
    if err := c.Bind(&input); err != nil {
        return problem.BadRequest("invalid signup payload").WithCause(err)
    }

    user, err := models.User{}.Create(ctx, map[string]any{
        "email": input.Email,
        "name":  input.Name,
    })
    if err != nil {
        return err
    }

    if err := v.Queue.PushCtx(ctx, jobs.SendWelcomeEmail{UserID: user.ID}); err != nil {
        return err
    }

    return c.JSON(201, user)
})

Validation, ORM, queue, and router — designed to work together.

Handlers return errors rather than writing error responses. The error pipeline reports each failure once and renders one answer that fits the request: application/problem+json for JSON clients, an error page for browsers, and, when a view engine is wired and the request carries a session, a failed validation flashes its errors and old input into the session and redirects back.

Why Velocity

Type-Safe ORM

Generic models return []User, not []interface{}. Queries are checked at compile time. If the types don't match, it doesn't build.

users, _ := User{}.Where("active = ?", true).
    OrderBy("created_at", "DESC").
    Limit(10).
    Get(ctx)

Queries · Relationships · Migrations

Swap Drivers, Not Code

Every subsystem uses pluggable drivers configured through environment variables.

Subsystem Drivers
Database PostgreSQL, MySQL, SQLite
Cache Memory, File, Redis
Queue Memory, Redis, Database
Storage Local, S3, Memory
Mail Postmark, Mailgun, Local (writes to disk)
Auth Sessions, JWT (plus access policies on top)
Broadcasting WebSocket (additional drivers planned)

SQLite in development, PostgreSQL in production. One env var:

DB_CONNECTION=sqlite    # or postgres, mysql
CACHE_DRIVER=redis      # or memory, file
QUEUE_DRIVER=redis      # or memory, database
STORAGE_DRIVER=s3       # or local, memory
MAIL_DRIVER=postmark    # or mailgun, local, log

Secure by Default

Safe defaults you opt out of, not into. Cookies ship Secure and SameSite=Lax, and the session and remember cookies HttpOnly; only XSRF-TOKEN is readable by JavaScript, by design, so a client can echo it back. CORS rejects every cross-origin request until you name the origins you trust. Mount the CSRF middleware and every state-changing method needs a token bound to a live session. The app won't start without an APP_KEY, and APP_DEBUG=true is ignored in production so stack traces never leak. The destructive CLI commands (db wipe, migrate fresh, migrate rollback) refuse to touch a production database unless you pass --force.

The lower-level pieces are conservative too:

Area Default
Crypto AES-256-GCM, random nonces, constant-time compares, HKDF subkey separation
Passwords bcrypt with an enforced cost floor
Auth JWT rejects alg=none and algorithm substitution; session ID rotates on login
Tokens 32-byte crypto/rand session and CSRF tokens
ORM parameterized queries, validated identifiers, deny-by-default mass assignment
Timestamps instants stored UTC on every write path regardless of host timezone; zones are presentation
Storage os.Root path containment (openat2 on Linux), no traversal or symlink escape
HTTP client SSRF guard blocks private and link-local ranges by default, TLS 1.2 floor

Security headers (HSTS, CSP), HTTPS redirect, and request throttling ship as middleware you wire into the stack. Insecure modes exist, but you ask for them by name (InsecureAllowAllCORS, GRPC_INSECURE).

React or Vue, Without a Separate API

Handlers render pages instead of serving JSON for a separate frontend. The Inertia adapter passes props straight to React 19 or Vue 3 components, Vite hot-reloads the frontend while vel serve rebuilds Go, and --ssr turns on server-side rendering. Need JSON only? Scaffold with velocity new myapi --api.

func Dashboard(ctx *router.Context) error {
    return view.Render(ctx, "Dashboard", view.Props{"stats": stats})
}

No Magic

No runtime reflection for dependency injection. No implicit model fetching. No hidden interceptors. Every line of code does what it says.

What's Included

Utility packages such as cache, crypto, validation, httpclient, log, str, and async also work on their own, outside a Velocity app; see Standalone packages. See vel.build/docs for the full list.

Testing

An in-memory app harness, model factories, database refresh, a fluent HTTP client, and fakes for events and the command bus. Refresh the schema, seed with a factory, drive a route, then chain assertions against the response:

tc := ormtesting.NewTestCase(t, manager)
tc.LazyRefreshDatabase() // migrate once, truncate per test

ormtesting.NewModelFactory[User](manager, newUser).
    State("admin").
    CreateOne(ctx, nil) // seed test data

velhttp.NewTestClient(t, router).
    ActingAs(scheme, user).
    PostJSON("/signup", map[string]any{"email": "[email protected]"}).
    AssertCreated().
    AssertJSONPath("user.email", "[email protected]")

Status, header, cookie, body, JSON-path, validation, and auth assertions all chain. Testing docs.

Commands

Each project builds its own ./vel binary for development and code generation. The vel launcher (installed with the Homebrew cask above) finds the project, rebuilds that binary, and runs it. Without the launcher, use ./vel <command> or go run . <command>.

vel serve                # dev server with live reload
vel build                # compile the production binary
vel migrate              # run migrations (also fresh, rollback, status)
vel queue work           # process queued jobs
vel schedule work        # run the scheduler
vel routes               # list registered routes (--json for machine-readable output)
vel cache clear          # flush the cache
vel key generate         # generate the app encryption key
vel up / vel down        # toggle maintenance mode
vel gen model User       # scaffold (model, handler, job, policy, module, migration, ...)

Full reference: vel.build/docs/cli/commands.

Versioning

Velocity follows semantic versioning. Until v1.0.0 ships, minor versions may include breaking API changes — always documented in CHANGELOG.md under the version's Breaking section.

Documentation

vel.build/docs

AI-Assisted Development

Arrow is a Velocity-aware MCP server that gives AI agents (Claude Code, Cursor, Codex, and more) the context to write correct Velocity code: app info, database schema, route listing, doc search, log reading, and config inspection, plus auto-generated guidelines and skills matched to your project.

go install github.com/velocitykode/velocity-arrow/cmd/arrow@latest

Velocity MCP lets you rapidly build your own MCP servers for Velocity applications, exposing tools, resources, and prompts to AI agents.

go get github.com/velocitykode/velocity-mcp

AI SDK (coming soon): a first-party module for calling LLM providers, generating embeddings, and running vector search from a Velocity application.

Community

License

Velocity is open-source software licensed under the MIT License.

Explore related projects