oniworks

module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: MIT

README

MIT License v1.0.0 PostgreSQL

OniWorks

The Go framework that thinks in realtime.

OniWorks is a batteries-included Go web framework inspired by Laravel, built for the era of live, connected applications. It provides a full MVC stack, a type-safe query builder, authentication, WebSockets, a distributed in-memory store, queues, a scheduler, and a Vite+TypeScript frontend layer — all with a single import.

event → socket → memory → broadcast → UI
                    ↓
             persist → PostgreSQL (when needed)

Repository: github.com/onipixel/oniworks · Maintained by OniPixel


Why OniWorks?

Most Go web libraries give you routing and leave the rest to you. OniWorks gives you the whole stack:

Feature Status
HTTP routing (radix tree, zero-alloc dispatch) + middleware
Query builder (PostgreSQL + MySQL) — upsert, aggregates, chunking, cursor pagination
Migrations + seeders
Auth (JWT + sessions + CSRF + RBAC)
Request validation (c.Validate(), custom messages)
WebSocket realtime (Oni Socket) — multi-node verified
Distributed in-memory store (Oni Memory) — gossip or Redis sync
Queue + background jobs (at-least-once, memory + Redis)
Scheduler / cron
Sessions (memory + Redis drivers)
Mail / SMTP
File storage (local + S3-compatible)
Auto TLS via Caddy (Oni Deploy)
CLI code generator (oni make:*)
Admin panel (auto-generated CRUD, CSRF-protected)
Prometheus metrics + health checks
Vite + TypeScript + Tailwind v4
TypeScript generation — types and a typed API client from your routes

Quick Start

# Install the CLI
go install github.com/onipixel/oniworks/cmd/oni@latest

# Create a new project
oni new my-app
cd my-app

# Configure .env, then:
oni migrate
oni serve

Hello World

package main

import (
    "github.com/onipixel/oniworks/framework/app"
    onihttp "github.com/onipixel/oniworks/framework/http"
    "github.com/onipixel/oniworks/framework/routing"
    "github.com/onipixel/oniworks/framework/middleware"
)

func main() {
    oni := app.New().Load(".env")

    oni.Use(middleware.Recovery(), middleware.Logger())

    oni.Route(func(r *routing.Router) {
        r.Get("/", func(c *onihttp.Context) error {
            return c.JSON(200, onihttp.Map{"message": "Hello from OniWorks!"})
        })
    })

    oni.Serve()
}

Realtime in 15 lines

hub := realtime.New(realtime.Options{Memory: mem})

// Server: route channel events
hub.Channel("chat.{room}", func(conn *realtime.Conn, e *realtime.Event) error {
    return hub.Broadcast("chat."+e.Params["room"], e.Payload)
})

// Mount on the router
r.Get("/ws", hub.Handler())
// Client (TypeScript) — npm install @oniworks/socket  (see client/)
import { OniSocket } from "@oniworks/socket"
const socket = new OniSocket("/ws")
socket.channel("chat.general").on("chat.message", (e) => appendMessage(e.payload))
socket.channel("chat.general").send("chat.message", { text: "hey!" })

Architecture

oniworks/
├── cmd/oni/          CLI (oni new, oni serve, oni make:*, oni migrate, ...)
├── framework/
│   ├── app/          Application bootstrap & IoC container
│   ├── http/         Router, context, middleware, validation binding
│   ├── routing/      Route groups, named routes, trie-based dispatch
│   ├── database/     Query builder, NULL-safe scanner, eager loading
│   ├── migrations/   Schema migration engine (Up/Down, batch rollback)
│   ├── seeder/       Database seeders
│   ├── auth/         JWT, sessions, bcrypt, CSRF, per-request auth
│   ├── roles/        RBAC — roles & permissions with wildcard support
│   ├── realtime/     Oni Socket — WebSocket hub, channels, presence
│   ├── memory/       Oni Memory — distributed KV + pub/sub + TTL
│   ├── queue/        Job queue (memory + Redis drivers, exponential backoff)
│   ├── scheduler/    Cron-style task scheduler (robfig/cron)
│   ├── mail/         SMTP mailer with template support
│   ├── storage/      File storage (local + S3-compatible)
│   ├── validation/   Struct-tag validation with custom rules
│   ├── config/       .env + YAML config
│   ├── secrets/      AES-256-GCM encrypted secrets
│   ├── logging/      Structured logger (slog)
│   ├── errors/       Rich debug pages (dev) / clean JSON (prod)
│   ├── health/       Health check endpoints
│   ├── metrics/      Prometheus metrics
│   ├── admin/        Auto-generated CRUD admin panel
│   ├── deploy/       Caddy integration + auto TLS
│   ├── backup/       Database backup & restore
│   └── frontend/     Vite manifest loader + TypeScript type generator
├── testing/
│   ├── stress/       Load test suite (HTTP, Memory, PostgreSQL, WebSocket)
│   └── onigram/      Integration test application
├── stubs/            Code generation templates
├── examples/         Example applications
└── sample/
    ├── oniworks-site/ Documentation website
    └── onimail/       OniMail — self-hosted email platform built with OniWorks

Core Concepts

Query Builder

Lazy, fluent, NULL-safe. Nothing executes until a terminal method is called:

// Single row — returns ErrNotFound if no match
var user User
err := db.Table("users").Where("id = ?", id).First(&user)

// Multiple rows with eager loading (no N+1)
var posts []Post
err := db.Table("posts").
    With("Author", "Tags").
    Where("published = ?", true).
    OrderBy("created_at DESC").
    All(&posts)

// Pagination
var posts []Post
page, err := db.Table("posts").
    Where("user_id = ?", userID).
    Paginate(1, 20, &posts)
// page.Total, page.LastPage, page.From, page.To

// Cursor (keyset) pagination — scales past OFFSET
next, err := db.Table("posts").Where("published = ?", true).
    CursorPaginate("id", lastID, 20, &posts)

// Soft deletes — with the full lifecycle
db.Table("posts").SoftDelete().Where("user_id = ?", id).All(&posts)
db.Table("posts").SoftDelete().OnlyTrashed().Where("user_id = ?", id).Restore()

// Aggregates, atomic counters, upserts
total, _ := db.Table("orders").Where("status = ?", "paid").Sum("amount")
db.Table("posts").Where("id = ?", id).Increment("views", 1)
db.Table("settings").UpsertMap(
    database.Map{"key": "theme", "value": "dark"},
    []string{"key"}, []string{"value"},
)

// Grouped conditions + subqueries
db.Table("users").
    WhereGroup(func(q *database.Builder) {
        q.Where("role = ?", "admin").OrWhere("role = ?", "editor")
    }).
    WhereInSub("team_id", db.Table("teams").Select("id").Where("active = ?", true)).
    All(&users)

// Batch processing without loading everything
db.Table("events").ChunkByID(1000, func(batch []map[string]any) error {
    return process(batch)
})

// Transactions with savepoints (auto-rollback + re-panic on panic)
err := db.Transaction(func(tx *database.DB) error {
    tx.Table("accounts").Where("id = ?", from).Update(database.Map{"balance": newBal})
    return tx.Table("accounts").Where("id = ?", to).Update(database.Map{"balance": newBal2})
})

// Debugging: see the SQL without running it
sql, args, _ := db.Table("users").Where("active = ?", true).ToSQL()
Request Validation

Bind and validate in one call:

func createUser(c *onihttp.Context) error {
    var in struct {
        Name  string `json:"name"  validate:"required,min=2"`
        Email string `json:"email" validate:"required,email"`
    }
    if err := c.Validate(&in); err != nil {
        return err // 422 {"message":"validation failed","errors":{...}}
    }
    // in.Name and in.Email are valid
}

Nested structs validate recursively, unknown rule names fail loudly instead of silently passing, and messages are customizable per validator (v.SetMessage("min", "{field} needs at least {param} characters")) or per field (validate_msg:"required=Please enter your name").

End-to-end types: Go → TypeScript

Generate TS interfaces from your Go structs and a typed, dependency-free fetch client from your named routes:

frontend.GenerateTypes("app/models", "resources/ts/types.generated.ts")
frontend.GenerateClient(router.Routes(), "resources/ts/api.generated.ts",
    frontend.WithTypesImport("./types.generated"),
    frontend.WithRouteTypes("user.show", "", "User"),
    frontend.WithRouteTypes("user.create", "CreateUserRequest", "User"),
)
import { api } from "./api.generated"

const user = await api.user.show({ id: 42 })          // Promise<User>
const made = await api.user.create({ name: "Alice" }) // typed body + response
// non-2xx throws ApiError with .status and the parsed body
Oni Socket — Realtime Platform

Oni Socket is not just a WebSocket wrapper — it is a full realtime platform:

  • Channel routing with {param} captures
  • Presence — know who is online per channel, across nodes, refreshed automatically
  • Backpressure — bounded send buffer per connection, slow clients dropped gracefully; broadcast cost is independent of how many connections the node holds
  • Per-connection auth (JWT or session, during HTTP upgrade)
  • Reconnect/resume with server-side event buffer and last_event_id replay (buffers evict when idle)
  • Cross-node broadcast via Oni Memory pub/sub (no Redis required by default) — covered by a real two-node integration test: a broadcast originating on node 2 reaches node 1's clients exactly once. See the scaling guide.
hub := realtime.New(realtime.Options{
    Memory: mem,
    AuthFunc: func(r *http.Request) (int64, error) {
        // return userID from session/JWT
    },
})

hub.Channel("orders.{userID}", func(conn *realtime.Conn, e *realtime.Event) error {
    return hub.Push(conn.ID(), &realtime.Event{Type: "order.update", Payload: e.Payload})
})

hub.Presence("room.{id}")  // tracks who's online per room

r.Get("/ws", hub.Handler())
Oni Memory — Distributed In-Memory Store
mem := memory.New(memory.Options{
    Persist:  true,         // snapshot on shutdown
    BindAddr: ":7946",      // enable TCP gossip for multi-node
})

mem.Set("session:abc", data, 2*time.Hour)
mem.Incr("page:views")                          // atomic counter
mem.CompareAndSwap("lock", nil, "held", 30*time.Second)

cancel := mem.Subscribe("orders.*", func(topic string, payload any) {
    // fan-out pub/sub — 7M+ effective messages/sec
})

Memory-first is the default everywhere: a single node needs no external services. For multi-node, choose your transport — the built-in gossip cluster (authenticated with a shared secret, vector-clock LWW with delete tombstones) or Redis (memory.Options{RedisURL}). Sessions and the queue have Redis drivers too. See docs/scaling.md.


Performance

The router is a per-method radix tree with pooled contexts and precomposed middleware chains — dispatch is zero-allocation and independent of how many routes you register (go test -bench . ./framework/routing/, Ryzen 9 7940HS):

Hot path (63 registered routes) ns/op allocs/op
Static route 47 0
Param route (/users/:id) 56 0
Param route + 3 middleware 60 0
Wildcard (/static/*filepath) 54 0

CI enforces this: a perf gate fails the build on any allocation regression, and a stress smoke runs on every push.

Under concurrent load (testing/stress, 50 workers, Go 1.25, Windows):

Component Test Throughput
HTTP Router GET (in-process) 1.6M req/s
HTTP Router GET with 2 params 1.4M req/s
HTTP Router POST + JSON bind 1.1M req/s
HTTP Router TCP round-trip 10K req/s
Oni Memory Get (10K keys) 8.7M ops/s
Oni Memory Incr (50-way contention) 2.9M ops/s
Oni Memory Pub/Sub (20 subscribers) 21M msg/s effective
PostgreSQL* SELECT by PK 194K qps
PostgreSQL* INSERT 59K qps
PostgreSQL* Transaction (R+W) 17K tx/s
WebSocket Round-trip echo 544K msg/s
WebSocket Broadcast delivery 100% to 50 conns (78,750/78,750)

*PostgreSQL rows are from an earlier run against a local Postgres 18; the rest were re-measured after the router rewrite.

Run it yourself: go run ./testing/stress --workers 50 --duration 8s


CLI

oni new <name>                  Create a new project (with .air.toml for hot reload)
oni new <name> --frontend       Create with Vite + TypeScript + Tailwind
oni new <name> --force          Overwrite an existing directory

oni serve                       Start dev server (uses Air if installed)
oni build                       Compile production binary
oni deploy --domain myapp.com   Deploy with Let's Encrypt TLS

# Generators
oni make:controller <Name>      HTTP controller
oni make:model <Name>           Database model
oni make:migration <name>       Migration file
oni make:middleware <Name>      Middleware
oni make:job <Name>             Background job
oni make:mail <Name>            Mailer
oni make:seeder <Name>          Database seeder
oni make:channel <Name>         WebSocket channel handler
oni make:policy <Name>          Authorization policy
oni make:test <Name>            Test scaffold
oni make:resource <Name>        Controller + model + migration

# Database
oni migrate                     Run pending migrations
oni migrate:rollback            Rollback last batch
oni migrate:fresh               Drop all + re-run
oni migrate:status              Show status table
oni db:seed                     Run seeders

# Operations
oni queue:work                  Start queue worker
oni schedule:run                Run scheduled tasks
oni route:list                  List all routes (--json for tooling)
oni key:generate                Generate APP_KEY
oni health                      Run health checks

Documentation

Guide
Getting Started Install, scaffold, first app
Routing Routes, params, middleware, groups
Database & ORM Query builder, eager loading, migrations
Authentication JWT, session auth, CSRF, RBAC
Realtime — Oni Socket WebSockets, channels, presence
Oni Memory KV store, pub/sub, distributed mode
Scaling Multi-node deployment — gossip vs Redis
Frontend Vite + TypeScript + Tailwind integration
CLI Reference All oni commands
Testing HTTP test helpers, assertions

📖 Full documentation site — coming soon at oniworks.dev


OniMail — Coming Soon

OniMail is a self-hosted email platform being built on top of OniWorks. It will be released as a separate package once it reaches a stable state.

Work in progress — core SMTP/IMAP/webmail functionality works, but several production features (admin UI, S3 storage, auto-TLS, quota enforcement) are still being completed.

What it will include:

  • Full SMTP + IMAP4rev2 server
  • Gmail-quality webmail (TypeScript + Tailwind)
  • Real-time inbox via Oni Socket
  • DKIM / SPF / DMARC authentication
  • Marketing campaigns with open/click tracking

Follow this repo for updates.


Status

v1.0.0. The framework has been through two full audit-and-hardening passes (security defaults, data-layer correctness, concurrency under load, hot-path performance) — every fix locked in with a regression test. 29 test packages, a live-Postgres integration suite, a two-node realtime integration test, and CI running the race detector, a perf-regression gate, a stress smoke, and a coverage ratchet.

  • Core HTTP layer + radix-tree router (zero-alloc dispatch)
  • Query builder — NULL-safe scanner, eager loading, upsert, aggregates, chunking, cursor pagination
  • Pagination + full soft-delete lifecycle (OnlyTrashed, Restore)
  • Request validation (c.Validate(), nested structs, custom messages)
  • Auth (JWT + sessions + CSRF + RBAC) — hardened, session rotation on login/logout
  • Oni Socket (WebSocket realtime) — cross-node broadcast + presence, verified by integration test
  • Oni Memory (distributed KV + pub/sub) — authenticated gossip or Redis sync
  • Queue (at-least-once, memory + Redis) + scheduler
  • Sessions (memory + Redis drivers)
  • Mail + storage (local + S3)
  • CLI generator (oni make:*) + working scaffold loop
  • Admin panel (fail-closed auth, CSRF)
  • Vite + TypeScript + Tailwind v4 + typed API client generation
  • TS realtime client (@oniworks/socket)
  • Stress suite + CI gates
  • v1.0.0 tagged — CI fully green (race detector, live Postgres, perf gate, stress)
  • Hosted documentation site (oniworks.dev)
  • OniMail package (coming soon)
  • OAuth / social login, 2FA, image processing (post-1.0)

See ROADMAP.md for the milestone history and CHANGELOG.md for the full list of changes — including breaking changes if you're upgrading from an earlier checkout.


Contributing

git clone https://github.com/onipixel/oniworks
cd oniworks
go mod download
go test ./...

# Run stress tests
go run ./testing/stress --workers 50 --duration 8s

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
oni command
Command oni is the OniWorks CLI — scaffold, migrate, serve, deploy, and more.
Command oni is the OniWorks CLI — scaffold, migrate, serve, deploy, and more.
examples
api command
Example: OniWorks REST API Demonstrates a minimal CRUD API with JWT auth, validation, and middleware.
Example: OniWorks REST API Demonstrates a minimal CRUD API with JWT auth, validation, and middleware.
fullstack command
Example: OniWorks Fullstack App Demonstrates HTTP + WebSocket + Vite frontend + Oni Memory + Queue + Mail.
Example: OniWorks Fullstack App Demonstrates HTTP + WebSocket + Vite frontend + Oni Memory + Queue + Mail.
realtime-chat command
Example: OniWorks Realtime Chat Demonstrates Oni Socket + Oni Memory for a cross-node realtime chat.
Example: OniWorks Realtime Chat Demonstrates Oni Socket + Oni Memory for a cross-node realtime chat.
framework
admin
Package admin provides Oni Admin — an auto-generated CRUD management panel.
Package admin provides Oni Admin — an auto-generated CRUD management panel.
app
Package app provides the IoC service container and application bootstrap.
Package app provides the IoC service container and application bootstrap.
auth
Package auth provides session-based and JWT authentication for OniWorks.
Package auth provides session-based and JWT authentication for OniWorks.
backup
Package backup provides database backup and restore utilities.
Package backup provides database backup and restore utilities.
config
Package config provides environment and file-based configuration with type-safe accessors.
Package config provides environment and file-based configuration with type-safe accessors.
database
Package database provides a high-performance query builder, struct scanner, lifecycle hooks, and explicit eager relationship loading for OniWorks.
Package database provides a high-performance query builder, struct scanner, lifecycle hooks, and explicit eager relationship loading for OniWorks.
deploy
Package deploy manages Caddy as an automatic TLS reverse proxy.
Package deploy manages Caddy as an automatic TLS reverse proxy.
errors
Package errors provides error handling utilities for OniWorks applications.
Package errors provides error handling utilities for OniWorks applications.
frontend
Package frontend provides helpers for serving Vite-built frontend assets embedded in the Go binary via go:embed, plus a development proxy for hot-module reload during development.
Package frontend provides helpers for serving Vite-built frontend assets embedded in the Go binary via go:embed, plus a development proxy for hot-module reload during development.
health
Package health provides an HTTP health-check endpoint and a registry for application-defined checks (database, queue, external services, etc.).
Package health provides an HTTP health-check endpoint and a registry for application-defined checks (database, queue, external services, etc.).
http
Package http provides the HTTP kernel, context, request, and response abstractions.
Package http provides the HTTP kernel, context, request, and response abstractions.
logging
Package logging provides structured logging helpers built on top of log/slog.
Package logging provides structured logging helpers built on top of log/slog.
mail
Package mail provides a fluent email API backed by go-mail (SMTP).
Package mail provides a fluent email API backed by go-mail (SMTP).
memory
Package memory provides the OniWorks distributed in-memory database.
Package memory provides the OniWorks distributed in-memory database.
metrics
Package metrics provides a Prometheus-compatible metrics endpoint and built-in framework metrics (HTTP request duration, active connections, etc.).
Package metrics provides a Prometheus-compatible metrics endpoint and built-in framework metrics (HTTP request duration, active connections, etc.).
middleware
Package middleware provides built-in OniWorks middleware.
Package middleware provides built-in OniWorks middleware.
migrations
Package migrations provides the database migration runner and schema builder for OniWorks.
Package migrations provides the database migration runner and schema builder for OniWorks.
queue
Package queue provides a lightweight job queue with in-memory and Redis drivers.
Package queue provides a lightweight job queue with in-memory and Redis drivers.
realtime
Package realtime is the OniWorks realtime platform — the nervous system of the framework.
Package realtime is the OniWorks realtime platform — the nervous system of the framework.
roles
Package roles provides a simple, performant RBAC (Role-Based Access Control) system.
Package roles provides a simple, performant RBAC (Role-Based Access Control) system.
routing
Package routing provides a high-performance segment-tree HTTP router.
Package routing provides a high-performance segment-tree HTTP router.
scheduler
Package scheduler wraps robfig/cron with a fluent API for defining scheduled tasks, named jobs, and graceful shutdown.
Package scheduler wraps robfig/cron with a fluent API for defining scheduled tasks, named jobs, and graceful shutdown.
secrets
Package secrets provides AES-256-GCM encryption for application secrets.
Package secrets provides AES-256-GCM encryption for application secrets.
seeder
Package seeder provides the database seeder system for OniWorks.
Package seeder provides the database seeder system for OniWorks.
session
Package session provides server-side session management for OniWorks.
Package session provides server-side session management for OniWorks.
session/drivers
Package drivers provides session store implementations.
Package drivers provides session store implementations.
storage
Package storage provides a unified file storage abstraction with local-disk and S3-compatible (AWS S3, MinIO, Wasabi, R2) drivers.
Package storage provides a unified file storage abstraction with local-disk and S3-compatible (AWS S3, MinIO, Wasabi, R2) drivers.
testing
Package testing provides test helpers for OniWorks applications.
Package testing provides test helpers for OniWorks applications.
validation
Package validation provides struct-tag-driven input validation for OniWorks.
Package validation provides struct-tag-driven input validation for OniWorks.
Package stubs embeds the code-generation templates used by the `oni make:*` generators.
Package stubs embeds the code-generation templates used by the `oni make:*` generators.
testing
stress command
OniWorks Stress Test
OniWorks Stress Test

Jump to

Keyboard shortcuts

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