Skip to main content

Introduction

Thanks for your interest in contributing to oForum! This forum application is intentionally simple — a single Go binary, server-rendered HTML, and PostgreSQL. Contributions that keep it that way are welcome. oForum is built to be:
  • Easy to self-host (one binary + one database)
  • Fast (pages render in milliseconds)
  • Simple to understand (plain SQL, no abstractions)
  • Minimal dependencies (only essential packages)

Design Principles

These principles guide all development decisions:

Single Binary

Everything compiles into one executable, including migrations and templates embedded via //go:embed

Zero Config

One env var (DATABASE_URL), sensible defaults for everything else. No config files.

Server-Rendered

HTML is generated on the server using Go’s html/template. No client-side framework.

Plain SQL

No ORM — just pgx and handwritten queries. Queries live in internal/db/.

Minimal Dependencies

Only Gin, pgx, bcrypt, and golang-migrate. That’s the entire dependency tree.

Fast

The binary starts in under a second. Pages should render in milliseconds.

Code Style Guidelines

Formatting

All code must pass gofmt before committing:
# Check formatting
gofmt -l $(find . -name '*.go' -not -path './.git/*')

# Format everything
gofmt -w $(find . -name '*.go' -not -path './.git/*')

Architecture Rules

Keep it simple. No abstractions for the sake of abstractions.
  • SQL queries go in internal/db/, not in handlers
  • Handlers should be thin — get data, build template data, render
  • No external JavaScript — if something needs interactivity, use vanilla JS in the template
  • Database changes require migration files (up and down)

Code Quality

# Vet for issues
go vet ./...

# Build check
go build ./...

# Run tests
go test ./...

Pull Request Process

1

Fork and Branch

Fork the repository and create a feature branch:
git checkout -b my-feature
2

Make Changes

Implement your feature or fix. Keep PRs focused — one feature or fix per PR.
3

Format and Vet

Run formatting and checks:
gofmt -w .
go vet ./...
4

Commit with Clear Message

Write a descriptive commit message explaining the “why” not just the “what”:
git commit -m "Add post search by tag and title"
5

Open Pull Request

Push your branch and open a PR. If it touches the database schema, include the migration files.
If your PR adds a new database field, you must include both .up.sql and .down.sql migration files.

Development Resources

Key Files

FilePurpose
main.go:273-311Template function registration
main.go:322-382Route definitions
internal/models/models.goAll data structures
internal/handlers/helpers.goTemplate helper functions
internal/auth/middleware.goAuthentication middleware

Documentation

What to Contribute

Good First Issues

  • Documentation improvements — clarify confusing sections
  • Bug fixes — fix reported issues
  • Tests — add test coverage
  • Template refinements — improve UI/UX

Larger Features

Before starting work on a major feature:
  1. Open an issue to discuss the approach
  2. Ensure it aligns with the design principles
  3. Keep the PR focused and reviewable

Getting Help

If you’re stuck or have questions:
  • Check the CONTRIBUTING.md in the repo
  • Open a GitHub issue with the question label
  • Review existing code in internal/ to see patterns

Ready to start? Head to Development Setup to get your environment running.

Build docs developers (and LLMs) love