nimbus

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 27 Imported by: 0

README

Nimbus

https://agentrouter.org/register?aff=iHLj Laravel-inspired web framework for Go. Convention over configuration, clear structure, and a pleasant DX.

Repository: github.com/CodeSyncr/nimbus

Versioning & stability (v1.0.0)

Nimbus v1.0.0 is the first release with a stable core under Semantic Versioning: we avoid breaking changes to the packages listed below; when unavoidable, we prefer deprecation for one minor release before a major bump.

Stable in v1 (SemVer)

These packages are intended as stable building blocks for applications:

router, http, middleware, validation, config, session, auth, database, lucid, queue, mail, errors, schedule, locale, health, metrics, logger, cache, encryption, resource, notification, hash, container, view, and the Nimbus CLI (cmd/nimbus).

Evolving / preview
  • plugins/telescope — Debugging dashboard; many panels are still placeholders. Treat as preview; UI and internal APIs may evolve in minor releases until called out as stable in release notes.
  • Integration-style plugins (plugins/ai, Scout, Socialite, etc.) — Pin versions in production; follow release notes for breaking changes until each plugin is explicitly marked stable.
  • studio — Optional tooling; not part of the core stability promise.
Not in v1
  • OAuth / first-party API tokens (Laravel Sanctum/Passport-class) — Not shipped in v1; plan your own bearer tokens or wait for a future release (see CHANGELOG.md).
Requirements
  • Go 1.26+ (see go.mod). CI uses go-version-file: go.mod.

Release checklist: V1_RELEASE.md · History: CHANGELOG.md

Features

  • Router – Express-style routes with :param placeholders, route groups, and middleware
  • Context – Request/response helpers: JSON(), Param(), Redirect()
  • Config – Environment-based config (.env + config/)
  • Middleware – Global and per-route middleware (Logger, Recover, CORS)
  • Error pages – Built-in, content-negotiated 404/500 pages: a styled HTML page for browsers and structured JSON for API clients (based on the Accept header), with a tracking error_id. Override via router.Fallback and custom handlers.
  • Validation – Struct validation with go-playground/validator
  • Database – GORM-based models with database.Model (ID, timestamps), migrations support
  • CLInimbus new, make:model, make:migration (Ace-style)

Project structure (Laravel-inspired)

├── app/
│   ├── controllers/
│   ├── models/
│   └── middleware/
├── bin/            # Server boot (bin/server.go)
├── config/
├── database/
│   └── migrations/
├── start/          # Routes, kernel (optional)
├── public/
├── main.go
├── go.mod
└── .env

Quick start

Install CLI

From the nimbus repo directory:

cd /path/to/nimbus
go install ./cmd/nimbus

If you get zsh: command not found: nimbus, add Go’s bin directory to your PATH. For zsh, run once:

echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

Then run nimbus again. You can also run your app without the CLI: go run main.go (no hot reload) or go run github.com/air-verse/air@v1.52.3 (hot reload).

Hot reload: nimbus serve runs air via go run, so you don’t install anything extra. The first run may download air once; after that, edits to .go and .nimbus files restart the app automatically. No need to add air to your app’s go.mod or run go mod tidy for it. Press Ctrl+C to stop the server; it shuts down gracefully and releases the port.

Create a new app
nimbus new myapp
cd myapp
go mod tidy
nimbus serve

Server runs at http://localhost:3333. You can also run go run main.go directly.

If you see reading ../go.mod: no such file or directory when running nimbus serve: your app’s go.mod has replace github.com/CodeSyncr/nimbus => ../, which points at the parent directory. If the app lives outside the nimbus repo (e.g. as a sibling), change it to:

replace github.com/CodeSyncr/nimbus => ../nimbus

So the path after => is the directory that contains the nimbus go.mod.

If you see missing go.sum entry for module providing package ... (imported by github.com/CodeSyncr/nimbus/...): your app’s go.sum is missing transitive dependencies from the local nimbus module. From your app directory run:

go mod tidy

Then run nimbus serve again.

Use the framework in your own app
package main

import (
	"github.com/CodeSyncr/nimbus"
	"github.com/CodeSyncr/nimbus/http"
	"github.com/CodeSyncr/nimbus/middleware"
)

func main() {
	app := nimbus.New()
	app.Router.Use(middleware.Logger(), middleware.Recover())

	app.Router.Get("/", func(c *http.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"hello": "nimbus"})
	})
	app.Router.Get("/users/:id", func(c *http.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"id": c.Param("id")})
	})

	// Route groups
	api := app.Router.Group("/api")
	api.Get("/posts", listPosts)
	api.Post("/posts", createPost)

	_ = app.Run()
}
Config & env

Set PORT, APP_ENV, APP_NAME, DB_DRIVER, DB_DSN in .env. Config is loaded via config.Load() in nimbus.New().

Database & models
import "github.com/CodeSyncr/nimbus/database"

// Connect (e.g. in bin/server.go)
db, _ := database.Connect(config.Database.Driver, config.Database.DSN)

// Model (embed database.Model)
type User struct {
	database.Model
	Name  string
	Email string
}
db.AutoMigrate(&User{})
Migrations

Run migrations from your app root:

nimbus db:migrate

Or directly: go run . migrate. Migrations use a Laravel-inspired schema builder. Create one with:

nimbus make:migration create_users

Then add the new migration to database/migrations/registry.go. Each migration runs once; already-run migrations are tracked in schema_migrations and shown as skipped on subsequent runs.

Validation
import "github.com/CodeSyncr/nimbus/validation"

type CreateUserRequest struct {
	Name  string `validate:"required,min=2"`
	Email string `validate:"required,email"`
}

func createUser(c *http.Context) error {
	var req CreateUserRequest
	if err := validation.ValidateRequestJSON(c.Request.Body, &req); err != nil {
		return c.JSON(http.StatusUnprocessableEntity, map[string]any{"errors": err})
	}
	// ...
}
Views (.nimbus, Edge-style)

Put templates in a views/ folder with the .nimbus extension. Use c.View("name", data) to render in a Laravel-inspired workflow.

Syntax (Edge-aligned):

Nimbus Description
{{ variable }} Output, HTML-escaped
{{{ variable }}} Output, unescaped (for rich content)
{{-- comment --}} Comment (stripped from output)
@if(cond)@elseif(cond)@else@endif Conditionals
@each(items)@endeach Loop; use {{ . }} for current item
@each(post in posts)@endeach Loop with named var; use {{ $post }}
@layout('layout') Wrap with layout; layout uses {{ .embed }} or {{ .content }}
{{ .csrfField }} CSRF hidden input (auto-injected when Shield enabled)
@dump(posts) Debug: pretty-print variable (or @dump(state) for all)
@card()@end Component: views/components/card.nimbus becomes @card()

Components: Create views/components/card.nimbus; use @card()@end in templates. Render the main slot with {{{ .slots.main }}} (Edge-style).

Example: views/home.nimbus

@layout('layout')
<h2>Hello, {{ name }}!</h2>
@if(.items)
  @each(items)
  <li>{{ . }}</li>
  @endeach
@else
  <p>No items.</p>
@endif

In your handler:

return c.View("home", map[string]any{"name": "Guest", "title": "Home", "items": []string{"A", "B"}})

Views are loaded from the views/ directory by default. Change with view.SetRoot("custom/views") in main.go.

Plugins & packages

Default plugins (auto-registered with nimbus new)
Plugin Description Docs
Drive File storage (fs, S3, GCS, R2, Spaces, Supabase) README
Transmit SSE for real-time server-to-client push README
Core packages
Package Description Docs
Queue Background jobs (sync, Redis, database, SQS, Kafka) README
Additional plugins (nimbus plugin install <name>)
Plugin Description Docs
Horizon Queue dashboard, metrics, failed jobs (Redis) README
Pulse Lightweight request / app metrics middleware plugins/pulse
Reverb WebSocket channel broadcasting (optional Redis fan-out) README
AI AI integration (OpenAI, Ollama, Anthropic, etc.) README
Inertia Inertia.js for Vue/React/Svelte SPAs README
Telescope Debugging and introspection dashboard README
MCP Model Context Protocol for AI clients README
Unpoly Progressive enhancement and partial page updates nimbus plugin install unpoly
Redis

Redis is used by Queue (QUEUE_DRIVER=redis), Transmit (TRANSMIT_TRANSPORT=redis), Horizon (failed jobs + live queue depths), and Reverb (multi-instance WebSocket fan-out). Set REDIS_URL=redis://localhost:6379 in .env when using these features.

Commands

Command Description
nimbus new <name> Create a new Nimbus app
nimbus serve Run the app from the app root
nimbus db:migrate Run database migrations
nimbus db:rollback Rollback the last migration
nimbus make:model <Name> Scaffold a model
nimbus make:migration <name> Scaffold a migration
nimbus queue:work Run the queue worker (processes background jobs)
nimbus plugin install <name> / nimbus plugin:install <name> Install a plugin (horizon, reverb, telescope, inertia, ai, mcp, …)

Publishing (for maintainers)

  1. Push to GitHub (repo must be public for go get):

    git remote add origin https://github.com/CodeSyncr/nimbus.git   # if not already set
    git push -u origin main
    
  2. Tag a version (so users can pin versions):

    git tag v1.0.0
    git push origin v1.0.0
    
  3. Install CLI (others can install from the repo):

    go install github.com/CodeSyncr/nimbus/cmd/nimbus@latest
    
  4. Use in another project:

    go get github.com/CodeSyncr/nimbus@v1.0.0
    

    After the first fetch, the module appears on pkg.go.dev automatically.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloseNoSQL

func CloseNoSQL(ctx context.Context) error

CloseNoSQL closes the default NoSQL connection.

func NoSQLCollection

func NoSQLCollection(name string) nosql.Collection

NoSQLCollection is a convenience that returns a Collection handle from the default NoSQL connection.

coll := nimbus.NoSQLCollection("users")
coll.InsertOne(ctx, user)

func SetDB

func SetDB(conn *DB)

SetDB is called by the framework (or hosting app) to make the database connection globally available to application code as *nimbus.DB.

func SetNoSQL

func SetNoSQL(driver nosql.Driver)

SetNoSQL is called by the framework (or hosting app) to make the NoSQL connection globally available as *nimbus.NoSQL.

func Transaction

func Transaction(fn func(tx *DB) error) error

Transaction runs fn inside a database transaction. It automatically commits if no error is returned, or rolls back if an error occurs.

Types

type App

type App struct {
	Config    *config.Config
	Router    *router.Router
	Server    *stdhttp.Server
	Container *container.Container
	Events    *events.Dispatcher
	Scheduler *schedule.Scheduler
	Health    *health.Checker
	// contains filtered or unexported fields
}

App is the core Nimbus application (AdonisJS-style).

func New

func New() *App

New creates a new Nimbus application with default config.

func (*App) Boot

func (a *App) Boot() error

Boot runs the full initialisation sequence:

  1. Provider Register (all)
  2. Plugin Register (all) — bind services
  3. Plugin DefaultConfig collected
  4. Provider Boot (all)
  5. Plugin Boot (all)
  6. Plugin capabilities applied (routes, middleware, views)

func (*App) NamedMiddleware

func (a *App) NamedMiddleware() map[string]router.Middleware

NamedMiddleware returns the merged map of named middleware from all plugins. Use in start/kernel.go or start/routes.go.

func (*App) OnBoot

func (a *App) OnBoot(fn func(*App))

OnBoot registers a callback that runs after providers/plugins have been booted and plugin routes/middleware have been applied, but before the server starts listening.

func (*App) OnShutdown

func (a *App) OnShutdown(fn func(*App))

OnShutdown registers a callback that runs during graceful shutdown, before plugin HasShutdown hooks are executed.

func (*App) OnStart

func (a *App) OnStart(fn func(*App))

OnStart registers a callback that runs right before the HTTP server begins serving requests (after Boot and listen/port selection).

func (*App) Plugin

func (a *App) Plugin(name string) Plugin

Plugin returns a registered plugin by name, or nil if not found.

func (*App) PluginConfig

func (a *App) PluginConfig(name string) map[string]any

PluginConfig returns the merged default config for a plugin, or nil.

func (*App) Plugins

func (a *App) Plugins() []Plugin

Plugins returns all registered plugins in registration order.

func (*App) Register

func (a *App) Register(p Provider)

Register adds a service provider. Call before Run.

func (*App) Run

func (a *App) Run() error

func (*App) RunTLS

func (a *App) RunTLS(certFile, keyFile string) error

RunTLS starts the HTTP server with TLS. If the configured port is busy, it automatically picks a free port. Listens for SIGINT/SIGTERM and gracefully shuts down to release the port.

func (*App) Shutdown

func (a *App) Shutdown() error

Shutdown calls Shutdown on every plugin that implements HasShutdown.

func (*App) Use

func (a *App) Use(plugins ...Plugin)

Use registers one or more plugins with the application. Call in bin/server.go before app.Run().

app.Use(
    &auth.Plugin{},
    &redis.Plugin{},
)

type BasePlugin

type BasePlugin struct {
	PluginName    string
	PluginVersion string
}

BasePlugin provides a no-op implementation of the Plugin interface. Embed it in your plugin struct so you only need to override the methods you care about.

type MyPlugin struct {
    nimbus.BasePlugin
}

func (*BasePlugin) Boot

func (b *BasePlugin) Boot(_ *App) error

func (*BasePlugin) Name

func (b *BasePlugin) Name() string

func (*BasePlugin) Register

func (b *BasePlugin) Register(_ *App) error

func (*BasePlugin) Version

func (b *BasePlugin) Version() string

type DB

type DB = lucid.DB

DB is Nimbus's high-level database handle. Controllers and services can depend on *nimbus.DB instead of importing gorm. It is defined as a type alias so that *nimbus.DB and *lucid.DB are identical types, but applications should reference the nimbus.DB name.

func Begin

func Begin() *DB

Begin starts a manual database transaction. The caller is responsible for calling Commit() or Rollback() on the returned *DB.

func Connection

func Connection(name string) *DB

Connection returns a named database connection from the connection manager. If the named connection exists, it returns it. Otherwise, falls back to the default connection.

db := nimbus.Connection("analytics")
db.Find(&events)

func GetDB

func GetDB() *DB

GetDB returns the global Nimbus database handle, or nil if not initialised. Application code should prefer using this over importing gorm directly.

type HasBindings

type HasBindings interface {
	Bindings(c *container.Container)
}

HasBindings allows a plugin to declare container bindings that are automatically registered during the Register phase. Use this to bind SDK clients, API wrappers, or any service the app can resolve.

func (p *StripePlugin) Bindings(c *container.Container) {
    c.Singleton("stripe", func() (*stripe.Client, error) {
        return stripe.New(os.Getenv("STRIPE_KEY"))
    })
}

type HasCommands

type HasCommands interface {
	Commands() []cli.Command
}

HasCommands allows a plugin to register CLI commands (Artisan-style). Commands are added to the Nimbus CLI and available via `nimbus <cmd>`.

func (p *SentryPlugin) Commands() []cli.Command {
    return []cli.Command{&SentryTestCommand{}}
}

type HasConfig

type HasConfig interface {
	DefaultConfig() map[string]any
}

HasConfig allows a plugin to declare default configuration values. The map is keyed by config name and merged into the application's configuration at boot time.

type HasEvents

type HasEvents interface {
	Listeners() map[string][]events.Listener
}

HasEvents allows a plugin to declare event listeners that are registered on the application's event dispatcher during boot.

func (p *AuditPlugin) Listeners() map[string][]events.Listener {
    return map[string][]events.Listener{
        "user.created": {p.onUserCreated},
        "order.placed": {p.onOrderPlaced},
    }
}

type HasHealthChecks

type HasHealthChecks interface {
	HealthChecks() map[string]health.Check
}

HasHealthChecks allows a plugin to report health status. Registered checks are added to the application's health checker.

func (p *RedisPlugin) HealthChecks() map[string]health.Check {
    return map[string]health.Check{
        "redis": func(ctx context.Context) error {
            return p.client.Ping(ctx).Err()
        },
    }
}

type HasMiddleware

type HasMiddleware interface {
	Middleware() map[string]router.Middleware
}

HasMiddleware allows a plugin to expose named middleware that can be assigned to routes or groups in start/kernel.go or start/routes.go.

type HasMigrations

type HasMigrations interface {
	Migrations() []database.Migration
}

HasMigrations allows a plugin to provide database migrations that are collected and can be run alongside application migrations.

type HasRoutes

type HasRoutes interface {
	RegisterRoutes(r *router.Router)
}

HasRoutes allows a plugin to mount its own HTTP routes onto the application router during boot.

type HasSchedule

type HasSchedule interface {
	Schedule(s *schedule.Scheduler)
}

HasSchedule allows a plugin to register periodic background tasks. The scheduler runs automatically when the app starts.

func (p *TelemetryPlugin) Schedule(s *schedule.Scheduler) {
    s.Every(5*time.Minute, "telemetry-flush", p.flush)
}

type HasShutdown

type HasShutdown interface {
	Shutdown() error
}

HasShutdown allows a plugin to run cleanup logic when the application is shutting down (e.g. closing connections, flushing buffers).

type HasViews

type HasViews interface {
	ViewsFS() fs.FS
}

HasViews allows a plugin to supply an embedded filesystem of .nimbus templates that are layered into the view engine.

type NoSQL

type NoSQL struct {
	nosql.Driver
}

NoSQL is Nimbus's high-level NoSQL handle. It wraps nosql.Driver so controllers depend on *nimbus.NoSQL instead of the lower-level nosql package directly.

func GetNoSQL

func GetNoSQL() *NoSQL

GetNoSQL returns the global NoSQL handle, or nil if not initialised.

func NoSQLConnection

func NoSQLConnection(name string) *NoSQL

NoSQLConnection returns a named NoSQL connection wrapped in *nimbus.NoSQL. Falls back to the default NoSQL connection if the name isn't registered.

store := nimbus.NoSQLConnection("mongo")
store.Collection("users").FindOne(ctx, filter, &user)

type Plugin

type Plugin interface {
	// Name returns the plugin's unique identifier (e.g. "stripe", "sentry").
	Name() string

	// Version returns the semantic version string (e.g. "1.0.0").
	Version() string

	// Register is called first for all plugins. Bind services into
	// app.Container here. Do not resolve other services yet.
	Register(app *App) error

	// Boot is called after every plugin (and provider) has registered.
	// Safe to resolve container bindings and perform initialisation
	// that depends on other services.
	Boot(app *App) error
}

Plugin is the base contract every Nimbus plugin must satisfy. A plugin has a name, a version, and two lifecycle hooks that mirror the Provider pattern (Register → Boot).

Plugins may optionally implement one or more capability interfaces to hook into the framework at well-defined points. This design allows integrating anything — Stripe, Sentry, MongoDB, WhatsApp, etc.

type Provider

type Provider interface {
	Register(app *App) error
	Boot(app *App) error
}

Provider is the service provider interface (AdonisJS/Laravel style). Register runs first (bind services); Boot runs after all providers are registered.

Directories

Path Synopsis
socialite
Package socialite provides OAuth2-based social authentication (similar to Laravel Socialite).
Package socialite provides OAuth2-based social authentication (similar to Laravel Socialite).
cli
ui
cmd
nimbus command
Package main - plugin install command and registry.
Package main - plugin install command and registry.
Package edge provides an edge function runtime for Nimbus.
Package edge provides an edge function runtime for Nimbus.
Package events provides a lightweight pub/sub event dispatcher for Nimbus.
Package events provides a lightweight pub/sub event dispatcher for Nimbus.
Package http re-exports commonly used net/http symbols so that consumers only need a single import: "github.com/CodeSyncr/nimbus/http".
Package http re-exports commonly used net/http symbols so that consumers only need a single import: "github.com/CodeSyncr/nimbus/http".
internal
repl
Package repl provides an interactive Go REPL.
Package repl provides an interactive Go REPL.
clause
Package clause re-exports GORM clause builders under the Nimbus lucid module.
Package clause re-exports GORM clause builders under the Nimbus lucid module.
logger
Package logger re-exports GORM's logger types under the Nimbus lucid module.
Package logger re-exports GORM's logger types under the Nimbus lucid module.
Package metrics provides a lightweight, Prometheus-compatible metrics collector for Nimbus applications.
Package metrics provides a lightweight, Prometheus-compatible metrics collector for Nimbus applications.
Package openapi provides full OpenAPI 3.0 specification generation from Nimbus router routes.
Package openapi provides full OpenAPI 3.0 specification generation from Nimbus router routes.
packages
plugins
admin
Package admin is a resource-based CRUD admin panel for Nimbus, modeled on Laravel Nova / Filament.
Package admin is a resource-based CRUD admin panel for Nimbus, modeled on Laravel Nova / Filament.
ai
cashier
Package cashier is a multi-gateway billing plugin for Nimbus, modeled on Laravel Cashier but gateway-agnostic.
Package cashier is a multi-gateway billing plugin for Nimbus, modeled on Laravel Cashier but gateway-agnostic.
cashier/contracts
Package contracts defines the payment-gateway contract and the shared value types every gateway and the manager operate on.
Package contracts defines the payment-gateway contract and the shared value types every gateway and the manager operate on.
cashier/events
Package events defines canonical, gateway-agnostic payment events and maps each gateway's raw webhook types onto them — so paywall logic (grant/revoke) is written once regardless of which gateway delivered the event.
Package events defines canonical, gateway-agnostic payment events and maps each gateway's raw webhook types onto them — so paywall logic (grant/revoke) is written once regardless of which gateway delivered the event.
cashier/gateways
Package gateways holds the concrete payment gateways (Stripe, Razorpay, PayU, …).
Package gateways holds the concrete payment gateways (Stripe, Razorpay, PayU, …).
cashier/models
Package models holds the persisted Cashier tables (transactions, subscriptions) and their migrations.
Package models holds the persisted Cashier tables (transactions, subscriptions) and their migrations.
mcp
passport
Package passport is an OAuth2 authorization server for Nimbus, modeled on Laravel Passport.
Package passport is an OAuth2 authorization server for Nimbus, modeled on Laravel Passport.
passport/models
Package models holds the persisted Passport (OAuth2 server) tables: clients, authorization codes, access tokens, and refresh tokens.
Package models holds the persisted Passport (OAuth2 server) tables: clients, authorization codes, access tokens, and refresh tokens.
pulse
Package pulse provides lightweight application monitoring for Nimbus applications.
Package pulse provides lightweight application monitoring for Nimbus applications.
Package schedule provides a lightweight cron-style task scheduler for Nimbus.
Package schedule provides a lightweight cron-style task scheduler for Nimbus.
Package scheduler is DEPRECATED.
Package scheduler is DEPRECATED.
Package search provides full-text search capabilities similar to Laravel Scout.
Package search provides full-text search capabilities similar to Laravel Scout.
Package serverless adapts a Nimbus application (any http.Handler, such as app.Router) to serverless invocation models — starting with AWS Lambda.
Package serverless adapts a Nimbus application (any http.Handler, such as app.Router) to serverless invocation models — starting with AWS Lambda.
Package shield provides AI-powered request protection middleware for Nimbus.
Package shield provides AI-powered request protection middleware for Nimbus.
Package studio provides a built-in admin panel for Nimbus applications.
Package studio provides a built-in admin panel for Nimbus applications.
browser
Package browser is a Dusk-style end-to-end testing harness for Nimbus.
Package browser is a Dusk-style end-to-end testing harness for Nimbus.

Jump to

Keyboard shortcuts

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