gokart

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 9 Imported by: 0

README

GoKart Logo

GoKart

Opinionated Go service toolkit. Thin wrappers around best-in-class packages with sensible defaults, so the repetitive setup is handled and you can get to the interesting part.

Note: Not affiliated with Praetorian's GoKart (static security scanner). This GoKart is a service/CLI toolkit.

Why?

Every Go service has the same 50-100 lines of setup boilerplate: configure slog with JSON/text switching, set up chi with standard middleware, parse postgres URLs with pool limits, wire viper to read config + env vars. You have run this experiment dozens of times. It works, but it is tedious and easy to get slightly wrong.

GoKart turns that repeatable setup into one clean, reliable move.

app := cli.NewApp("myapp", "1.0.0").
    WithDescription("My tool").
    WithStandardFlags()
app.AddCommand(cli.Command("run", "Execute task", runTask))
app.Run()

Five lines. Real app. No ceremony.

  • Start fast with a CLI, then grow into an HTTP microservice using the same core GoKart tools.

It's not a framework. No hidden runtime. Factory functions return *pgxpool.Pool, chi.Router, *redis.Client - use them directly. If you disagree with a default, change it or use the underlying package. GoKart doesn't lock you in.

And for web services, the same philosophy:

pool, _ := postgres.Open(ctx, os.Getenv("DATABASE_URL"))
router := web.NewRouter(web.RouterConfig{Middleware: web.StandardMiddleware})
cache, _ := cache.Open(ctx, "localhost:6379")

Philosophy

  • Modular — Import only what you need. Each component is its own Go module.
  • Thin wrappers — GoKart doesn't reinvent. It wraps battle-tested packages.
  • Sensible defaults — Zero-config works. Customize when needed.
  • Fight for inclusion — If stdlib or the underlying package already solves it well, it stays out.

Quick Start

go install github.com/dotcommander/gokart/cmd/gokart@latest

gokart new mycli           # Structured CLI project
gokart new mycli --sqlite  # With SQLite wiring
gokart new mycli --ai      # With OpenAI client
gokart new mycli --postgres --ai  # Full stack

See Getting Started for a full walkthrough: scaffold, add integrations, run tests.

Components

Package Description Docs
gokart/cli App builder, styled output, tables, spinners, editor bridge CLI Package
cmd/gokart gokart new + gokart add project scaffolder Generator
gokart Typed config (viper), state persistence, logger aliases Root Package
gokart/logger slog wrapper — JSON/text, file logger for TUI tools Logger
gokart/web chi router, graceful server, response helpers, templ, validation, CSRF, pagination Web Toolkit
gokart/postgres pgx/v5 connection pool, transaction helper PostgreSQL
gokart/sqlite Zero-CGO SQLite, WAL mode, transaction helper SQLite
gokart/migrate goose/v3 schema migrations, embedded FS support Migrations
gokart/cache Redis client, Remember pattern, distributed locks Cache
gokart/ai openai-go v3 client factory OpenAI
Install packages individually
go get github.com/dotcommander/gokart           # Config, state, logger
go get github.com/dotcommander/gokart/cli        # CLI framework
go get github.com/dotcommander/gokart/web        # Router, server, templ, validation
go get github.com/dotcommander/gokart/postgres   # PostgreSQL pool
go get github.com/dotcommander/gokart/sqlite     # SQLite (zero CGO)
go get github.com/dotcommander/gokart/cache      # Redis cache
go get github.com/dotcommander/gokart/migrate    # Database migrations
go get github.com/dotcommander/gokart/ai         # OpenAI client

Examples

See examples/ for complete working examples:

  • http-service/ — Minimal HTTP API with chi router
  • cli-app/ — CLI with commands, tables, and spinners

Additional runnable examples for every component: docs/examples/


Not Included

GoKart intentionally excludes:

What Why Use Instead
Error helpers stdlib sufficient errors.Is/As, fmt.Errorf("%w")
File utilities stdlib sufficient os, io, filepath
String utilities stdlib sufficient strings
Env helpers viper handles it viper.AutomaticEnv()
DI container architecture choice Constructor injection
AI/LLM clients now a subpackage github.com/dotcommander/gokart/ai
Document processing domain-specific Separate packages

Compatibility

Minimum Go version: 1.22+ (1.26+ recommended)

Stability:

  • Library API (gokart, gokart/cli): Follows semver. Breaking changes only in major versions.
  • Generator templates (gokart new): May evolve between minor versions. Generated code is yours to modify.

License

MIT

Documentation

Overview

Package gokart provides thin wrappers around best-in-class Go packages with sensible defaults.

GoKart is an opinionated service toolkit. Every component must justify its existence - we wrap battle-tested packages, not reinvent them.

Components

Root module (github.com/dotcommander/gokart):

  • Config: viper wrapper for config files + env vars
  • State: JSON state persistence for CLI tools
  • Server: HTTP server with graceful shutdown
  • Logger: slog aliases (use gokart/logger directly)

Submodules:

  • gokart/logger: slog wrapper with JSON/text formatting
  • gokart/cli: CLI framework wrapping cobra + lipgloss
  • gokart/web: HTTP router, client, templ helpers, validator
  • gokart/postgres: pgx/v5 connection pool
  • gokart/sqlite: modernc.org/sqlite (zero CGO) with WAL mode
  • gokart/cache: go-redis/v9 with convenience methods
  • gokart/migrate: goose/v3 schema migrations
  • gokart/ai: OpenAI client factory functions

Design Principles

  • Thin wrappers: No business logic, just factory functions
  • Sensible defaults: Zero-config works for development and production
  • Best-in-class: Wrap proven packages, don't reinvent
  • Fight for inclusion: stdlib-sufficient things stay in stdlib

Quick Start

// Logger
log := logger.New(logger.Config{Level: "info", Format: "json"})

// Config
cfg, err := gokart.LoadConfig[AppConfig]("config.yaml")

// Router (gokart/web)
router := web.NewRouter(web.RouterConfig{Middleware: web.StandardMiddleware})

// PostgreSQL (gokart/postgres)
pool, err := postgres.Open(ctx, "postgres://localhost/mydb")

// Cache (gokart/cache)
c, err := cache.Open(ctx, "localhost:6379")

// Migrations (gokart/migrate)
migrate.Postgres(ctx, db, "migrations")

CLI Subpackage

For CLI applications, use the gokart/cli subpackage which wraps cobra and lipgloss:

import "github.com/dotcommander/gokart/cli"

app := cli.NewApp("myapp", "1.0.0").
    WithDescription("My application").
    WithStandardFlags()
app.Run()

Not Included

GoKart intentionally excludes things where stdlib is sufficient:

  • Error handling: use errors.Is/As and fmt.Errorf("%w", err)
  • File operations: use os, io, filepath
  • String manipulation: use strings
  • Environment variables: viper.AutomaticEnv() handles this

Domain-specific packages (AI/ML, document processing) belong in separate modules.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadConfig

func LoadConfig[T any](paths ...string) (T, error)

LoadConfig loads configuration from the first available file path into type T.

Features:

  • Supports multiple config paths (first found wins)
  • Automatic environment variable binding
  • DOT to UNDERSCORE env key mapping (e.g., db.host → DB_HOST)

Supported formats: JSON, YAML, TOML, HCL, envfile, Java properties

Example:

type Config struct {
    DB struct {
        Host string `mapstructure:"host"`
        Port int    `mapstructure:"port"`
    } `mapstructure:"db"`
}
cfg, err := gokart.LoadConfig[Config]("config.yaml", "config.json")

func LoadConfigWithDefaults

func LoadConfigWithDefaults[T any](defaults T, paths ...string) (T, error)

LoadConfigWithDefaults loads configuration with default values pre-populated.

The defaults parameter provides fallback values that will be overridden by values from config files or environment variables.

Example:

defaults := Config{
    DB: struct{Host string; Port int}{
        Host: "localhost",
        Port: 5432,
    },
}
cfg, err := gokart.LoadConfigWithDefaults(defaults, "config.yaml")

func LoadState

func LoadState[T any](appName, filename string) (T, error)

LoadState loads typed state from ~/.config/{appName}/{filename}.

Returns zero value and os.ErrNotExist if the file doesn't exist. This allows callers to distinguish between missing file and parse errors.

Example:

state, err := gokart.LoadState[AppState]("myapp", "state.json")
if errors.Is(err, os.ErrNotExist) {
    // First run, use defaults
    state = AppState{WindowSize: 800}
} else if err != nil {
    return err
}

func LogPath

func LogPath(appName string) string

LogPath returns the path where file logs are written. Deprecated: Use logger.Path directly.

func NewFileLogger

func NewFileLogger(appName string) (*slog.Logger, func(), error)

NewFileLogger creates a logger that writes to a temp file. Deprecated: Use logger.NewFile directly.

func NewLogger

func NewLogger(cfg LogConfig) *slog.Logger

NewLogger creates a new structured logger with sensible defaults. Deprecated: Use logger.New directly.

Example
package main

import (
	"github.com/dotcommander/gokart"
)

func main() {
	log := gokart.NewLogger(gokart.LogConfig{
		Level:  "info",
		Format: "json",
	})
	log.Info("server started", "port", 8080)
}

func SaveState

func SaveState[T any](appName, filename string, data T) error

SaveState saves typed state to ~/.config/{appName}/{filename}.

The file is written as indented JSON for human readability. Directory is created with 0755, files with 0644 permissions.

Example:

type AppState struct {
    LastOpened string `json:"last_opened"`
    WindowSize int    `json:"window_size"`
}
err := gokart.SaveState("myapp", "state.json", AppState{
    LastOpened: "/path/to/file",
    WindowSize: 1024,
})

func StatePath

func StatePath(appName, filename string) string

StatePath returns the full path to a state file.

Returns empty string if the user config directory cannot be determined.

Example:

path := gokart.StatePath("myapp", "state.json")
// Returns: /Users/username/.config/myapp/state.json (on macOS)

Types

type LogConfig

type LogConfig = logger.Config

LogConfig is an alias for logger.Config. Deprecated: Use logger.Config directly.

Directories

Path Synopsis
cache module
cli module
cmd
gokart command
internal
logger module
migrate module
postgres module
sqlite module
web module

Jump to

Keyboard shortcuts

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