A modern Go web framework with clean architecture and powerful development tools. Gohst provides a solid foundation for building scalable web applications with a clear separation between framework and application code.
Gohst follows a layered architecture with clean separation of concerns:
- Framework Layer (
internal/) - Core framework functionality that can be reused across projects - Application Layer (
app/) - Your specific business logic and application configuration - Interface-based Dependency Injection - Framework depends on app through well-defined interfaces
This design allows the framework to evolve independently while keeping your application code clean and testable.
- ποΈ Clean Architecture - Separation between framework and application layers
- οΏ½ Interface-based DI - Framework depends on app through interfaces, not direct coupling
- οΏ½π Hot-reloading - Go server using Air for rapid development
- π¨ Modern Frontend - Vite for asset building with TypeScript, Tailwind CSS
- π³ Docker Development - Postgres and PgAdmin in containers
- π¦ Flexible Sessions - File or Redis-based session storage
- ποΈ Advanced Database - Multi-database support with generic models and relationships
- π Robust Migrations - Database migrations and seeding with batch tracking
- π οΈ Template System - HTML rendering with layouts, partials, and custom functions
- βοΈ Rich Configuration - Environment-based config with feature flags and validation
- π Authentication - Built-in auth with role-based permissions
- π Form Handling - Type-safe forms with validation and error handling
gohst/
βββ app/ # π’ APPLICATION LAYER
β βββ config/ # App-specific configuration
β β βββ app.go # Feature flags, pagination, uploads
β β βββ db.go # Database connections setup
β β βββ README.md # Configuration documentation
β βββ controllers/ # Application controllers
β βββ helpers/ # App-specific template functions
β βββ models/ # Business domain models
β βββ routes/ # Application route definitions
β βββ services/ # Business logic services
βββ internal/ # π§ FRAMEWORK LAYER
β βββ auth/ # Authentication framework
β βββ config/ # Framework configuration & interfaces
β βββ controllers/ # Base controller functionality
β βββ db/ # Database connection management
β βββ forms/ # Form handling and validation
β βββ middleware/ # HTTP middleware (auth, CSRF, logging)
β βββ migration/ # Database migration engine
β βββ models/ # Generic model base with relationships
β βββ render/ # Template rendering and asset management
β βββ routes/ # Route registration and handling
β βββ session/ # Session management (file/Redis)
β βββ utils/ # Framework utilities
β βββ validation/ # Input validation framework
βββ cmd/ # π COMMANDS
β βββ migrate/ # Database migration CLI
β βββ web/ # Main web application
β βββ dev/ # Development tools
β βββ gohst_server # Development server control
β βββ docker_sql_build # Database setup
β βββ docker_sql_clear # Database cleanup
βββ database/ # π DATABASE
β βββ migrations/ # SQL migration files
β βββ seeds/ # SQL seed files
βββ templates/ # π¨ TEMPLATES
β βββ layouts/ # Layout templates
β βββ components/ # Reusable components
β βββ partials/ # Partial templates
β βββ views/ # Page templates
βββ assets/ # π¨ FRONTEND ASSETS
β βββ css/ # Stylesheet sources
β βββ js/ # JavaScript/TypeScript sources
β βββ icons/ # SVG icons
βββ static/ # π STATIC FILES
β βββ dist/ # Compiled frontend assets
β βββ images/ # Static images
β βββ uploads/ # User uploads
βββ docker/ # π³ DOCKER
β βββ postgres/ # Postgres container setup
β βββ pgadmin/ # PgAdmin configuration
βββ tmp/ # ποΈ TEMPORARY
β βββ sessions/ # File-based sessions
β βββ build-errors.log # Development logs
βββ .air.toml # Air hot-reload configuration
βββ .env # Environment variables
βββ docker-compose.yml # Docker services
βββ gohst # π» CLI tool
βββ go.mod # Go module
βββ package.json # Frontend dependencies
βββ tailwind.config.js # Tailwind CSS configuration
βββ vite.config.js # Vite build configuration
git clone https://github.com/jason-horvath/gohst.git
cd gohst
cp .env.example .envEdit .env with your specific settings:
APP_NAME="My CRM App"
DB_NAME=my_crm_db
DB_USER=my_user
DB_PASSWORD=my_password./gohst buildThis will:
- Start Docker containers (Postgres, PgAdmin)
- Install frontend dependencies
- Set up database connections
- Run initial migrations and seeds
./gohst devYour application will be available at:
- App: http://localhost:3030
- PgAdmin: http://localhost:5050 ([email protected] / password)
# Create a migration
./gohst migrate:create create_companies_table
# Create app models
# app/models/company.go
# Create controllers
# app/controllers/company_controller.go
# Add routes
# app/routes/routes.go- Clean separation - Framework code isolated in
internal/ - Interface-driven - Framework depends on app through interfaces
- Testable - Each layer can be tested independently
- Reusable - Framework can be extracted for other projects
- Focused business logic - App code stays in
app/ - Configuration flexibility - Environment-driven config with sensible defaults
- Type safety - Generic models and form validation
- Developer experience - Hot reloading, error handling, debugging tools
The gohst CLI tool is your primary interface for development, database management, and deployment tasks.
./gohst <command> [arguments]build- Build the complete development environment (Docker, NPM, Migrations)dev- Start the development environment (Docker, Vite, Air)dev:down- Stop the development environmentdestroy- Destroy the environment (removes containers, volumes, node_modules)server:start- Start the Go server (Air) independentlyserver:stop- Stop the Go serverdocker:rebuild- Rebuild Docker containersdocker:sql:build- Set up database initialization filesdocker:sql:clear- Clear database initialization filesstorage:link- Link storage assets to the static directory
migrate:run- Run all pending migrationsmigrate:status- Show migration statusmigrate:rollback- Rollback the last batch of migrationsmigrate:create <name>- Create a new migration filemigrate:full- Run migrations and seeds togethermigrate:fresh- Drop all tables and re-run all migrationsmigrate:fresh:full- Drop all tables, re-run migrations, and run seeds
migrate:seed- Run all pending seedsmigrate:seed:status- Show seed statusmigrate:seed:fresh- Clear all seed records and re-run all seedsmigrate:seed:rollback- Rollback the last batch of seedsmigrate:seed:create <name>- Create a new seed file
# Start working
./gohst dev
# Create a new migration
./gohst migrate:create create_users_table
# Run migrations
./gohst migrate:run
# Reset database completely
./gohst migrate:fresh:fullAdd an alias to your shell configuration:
# For zsh
echo 'alias gohst="./gohst"' >> ~/.zshrc
source ~/.zshrc
# For bash
echo 'alias gohst="./gohst"' >> ~/.bashrc
source ~/.bashrcOnce the alias is added only gohst <command> is needed to run commands.
-
Start the environment:
./gohst dev
-
Make changes - Air automatically reloads Go code, Vite handles frontend assets
-
Create database changes:
./gohst migrate:create add_user_preferences # Edit the generated migration file ./gohst migrate:run -
Add new features:
- Create models in
app/models/ - Add controllers in
app/controllers/ - Define routes in
app/routes/ - Create templates in
templates/
- Create models in
-
Update configuration:
- Modify
app/config/app.gofor business settings - Update
.envfor environment-specific values
- Modify
When building your app, you may need to enhance the framework:
- Identify the need - Missing validation, model feature, etc.
- Implement in
internal/- Keep framework code separate - Test with your app - Ensure it works for your use case
- Consider extraction - Framework improvements can benefit other projects
# Build for production
NODE_ENV=production npm run build
CGO_ENABLED=0 GOOS=linux go build -o app cmd/web/main.go
# Set production environment
APP_ENV_KEY=production
SESSION_STORE=redis
DB_HOST=production-db.example.com
# Run migrations
./gohst migrate:run
// Framework provides generic base models
type Company struct {
gohst.AppModel[Company]
Name string `db:"name"`
Industry string `db:"industry"`
}
// Automatic CRUD operations
company := &models.Company{}
err := company.Create(map[string]interface{}{
"name": "Acme Corp",
"industry": "Technology",
})
// Built-in soft deletes
err = company.SoftDelete(companyID)// Configure multiple databases
func CreateDBConfigs() *config.DatabaseConfigPool {
pool := config.NewDatabaseConfigPool()
// Primary database
pool.AddDatabase("primary", config.DatabaseConfig{
Host: "localhost",
Port: 5432,
User: "app",
Password: "secret",
DBName: "myapp",
SSLMode: "disable",
})
// Analytics database
pool.AddDatabase("analytics", config.DatabaseConfig{
Host: "analytics.example.com",
Port: 5432,
User: "readonly",
Password: "secret",
DBName: "analytics",
SSLMode: "require",
})
return pool
}
// Use specific database
analyticsDB := db.GetDB("analytics")// App-specific template functions
func AppTemplateFuncs() template.FuncMap {
return template.FuncMap{
"formatCurrency": func(amount float64) string {
return fmt.Sprintf("$%.2f", amount)
},
"userCan": func(user User, permission string) bool {
return user.HasPermission(permission)
},
"appVersion": func() string {
return appConfig.App.Version
},
}
}
// Register with framework
render.RegisterTemplateFuncs(appHelpers.AppTemplateFuncs())// Type-safe form handling
type CompanyForm struct {
Name string `form:"name" validate:"required,min=2"`
Industry string `form:"industry" validate:"required"`
Website string `form:"website" validate:"url"`
}
func (c *CompanyController) Create(w http.ResponseWriter, r *http.Request) {
form := &CompanyForm{}
if err := forms.ParseAndValidate(r, form); err != nil {
// Handle validation errors
c.RenderWithErrors(w, r, "companies/new", form, err)
return
}
// Form is valid, proceed with business logic
}Gohst provides two session storage options:
- Sessions are stored as
.sessionfiles in thetmp/sessions/directory - Uses Go's
gobencoding format for serialization - Each session is stored in a separate file with the pattern
{session-id}.session - Good for development and simple applications
- Configure in
.env:
SESSION_STORE=file
SESSION_FILE_PATH=tmp/sessions- Sessions are stored in Redis for better performance and scalability
- Recommended for production environments
- Configure in
.env:
SESSION_STORE=redis
SESSION_REDIS_HOST=localhost
SESSION_REDIS_PORT=6379
SESSION_REDIS_PASSWORD=
SESSION_REDIS_DB=0Common session configuration:
SESSION_NAME=session_id # Cookie name
SESSION_LENGTH=60 # Session duration in minutes
SESSION_CONTEXT_KEY=session # Context key for session dataGohst uses a layered configuration approach with framework and application layers:
The framework provides core functionality configuration:
- Database connections and pooling
- Session management (file/Redis)
- Template rendering and assets
- Middleware and routing
- Migration system
Your application extends the framework with business-specific config:
// app/config/app.go
type AppConfig struct {
Name string
Version string
Environment string
Debug bool
// Feature flags
Features FeatureFlags
// Business settings
Pagination PaginationConfig
Upload UploadConfig
}All configuration can be controlled via environment variables:
# Application
APP_NAME="My Gohst App"
APP_VERSION="1.0.0"
APP_ENV_KEY="production"
APP_DEBUG=false
APP_URL="https://myapp.com"
APP_PORT=3030
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=myapp
DB_PASSWORD=secret
DB_NAME=myapp_production
DB_SSL_MODE=disable # disable, require, verify-ca, verify-full
# Session Management
SESSION_STORE=redis # or 'file'
SESSION_NAME=session_id
SESSION_LENGTH=60 # minutes
SESSION_REDIS_HOST=localhost
SESSION_REDIS_PORT=6379
# Feature Flags
FEATURE_REGISTRATION=true
FEATURE_USER_PROFILES=true
FEATURE_NOTIFICATIONS=false
MAINTENANCE_MODE=false
# Business Settings
PAGINATION_DEFAULT_LIMIT=20
PAGINATION_MAX_LIMIT=100
UPLOAD_MAX_FILE_SIZE=10485760 # 10MB in bytes
UPLOAD_PATH="static/uploads"
# Development
VITE_MANIFEST_PATH=static/dist/.vite/manifest.json
VITE_PORT=5174The framework depends on your application through clean interfaces:
// Framework defines what it needs
type AppConfigProvider interface {
GetURL() string
GetDistPath() string
IsProduction() bool
IsDevelopment() bool
}
// Your app implements the interface
func (ac *AppConfig) IsProduction() bool {
return ac.Environment == "production"
}
// Framework uses the interface
app := config.GetAppConfig()
if app.IsProduction() {
// Production-specific logic
}
- ποΈ App Layer Architecture - Clean separation between framework (
internal/) and application (app/) code - π Interface-Based DI - Framework depends on app through interfaces, enabling true decoupling
- ποΈ Multi-Database Support - Configure multiple database connections with connection pooling
- π Advanced Migrations - Batch tracking, rollbacks, and seeding with comprehensive CLI
- π¨ Generic Models - Type-safe models with built-in CRUD operations and relationship support
- π Enhanced Forms - Type-safe form parsing with validation and error handling
- βοΈ Rich Configuration - Feature flags, pagination settings, upload controls, and environment-based config
- π οΈ Template Functions - App-specific template helpers with framework registration
- π Improved Auth - Role-based authentication with session management
- π Developer Experience - Better debugging, error handling, and development workflow
The framework now clearly distinguishes between:
Framework Code (internal/):
- Reusable across projects
- Database connections and models
- HTTP routing and middleware
- Template rendering and assets
- Session management
- Form handling and validation
Application Code (app/):
- Business-specific logic
- Domain models and controllers
- Application configuration
- Custom template functions
- Business services and helpers
This architecture makes Gohst suitable for:
- Rapid prototyping - Start building immediately with solid foundations
- Production applications - Scalable architecture with clean separation
- Framework development - Easily extract and reuse framework components
- Team development - Clear boundaries between framework and application concerns
To create a new project using Gohst as your framework:
# Clone with fresh git history
git clone https://github.com/jason-horvath/gohst.git my-new-project
cd my-new-project
rm -rf .git
git init
git add .
git commit -m "Initial commit: New project using Gohst framework"
# Configure for your project
# 1. Update .env with your settings
# 2. Modify app/config/app.go with your business logic
# 3. Clear out example code and start buildingAs you build your application, you'll likely improve the framework:
# Make framework improvements (in internal/)
git add internal/
git commit -m "framework: add file upload utilities"
# Make application features (in app/)
git add app/ templates/ static/
git commit -m "app: add customer management"Later, you can extract framework improvements to benefit other projects:
# Extract framework commits
git log --oneline --grep="framework:"
# Port improvements back to main framework repo
git format-patch HEAD~5 --grep="framework:" --stdout > framework-improvements.patchThis project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Jason Horvath - [email protected]