Some Go web dev notes

Go’s Stability and Long-Term Maintainability

  • Many praise Go’s slow evolution and stable standard library. Code can be abandoned for years and then revived with minimal friction.
  • Dependency updates tend to be painless compared to JavaScript/frontend ecosystems, where frequent breakage and complex chains of dependencies are common.
  • This “boring but stable” quality is viewed as a major, often underrated advantage, especially for tools and long-lived internal apps.

Frameworks vs. Standard Library

  • Strong support for a “library over framework” mindset: net/http, standard testing, and basic logging are seen as sufficient for many services.
  • Others find the first days in Go frustrating: choosing routers, logging, DB drivers, migrations, DI patterns, etc., is slower than “batteries-included” frameworks like Rails, Django, or .NET.
  • Opinionated stacks (Echo, ent, HTMX, Bulma, beego, pagoda, authboss, etc.) divide opinion: some want them for speed; others distrust “magic” and lock‑in.

Routing, Templates, and Web Stack Choices

  • Newer net/http features (path parameters, methods) reduce the need for heavy routers; chi is popular as a thin stdlib wrapper; some are moving away from Gin in favor of Echo or chi.
  • html/template is seen as powerful but awkward: idiosyncratic APIs, surprising behaviors (e.g., stripping comments), weak typing, and difficult data/threading across nested templates.
  • Templ is frequently recommended as a more ergonomic, type-safe alternative that plays well with HTMX.

Databases, SQL, and Transactions

  • Common stack patterns: pgx for Postgres, sqlx or Jet for SQL helpers, goose/pgmigrate for migrations, SQLite for small apps.
  • sqlc gets mixed reviews: great for simple queries but limited for dynamic queries, complex relationships, and advanced DB features.
  • SQLite concurrency is tricky: SQLITE_BUSY errors, WAL mode, BEGIN CONCURRENT, and single-writer patterns are discussed.
  • There’s a debate on transaction retries: some argue all DB work should be wrapped in bounded retry loops; others say blind retries can hide misconfiguration and overload the DB.

Deployment, Performance, and Ops

  • Static binaries plus embed for static assets make deployment trivial (copy one file, maybe add systemd); widely contrasted with Python/Ruby’s virtualenvs, WSGI, and native deps.
  • Built-in TLS in net/http is considered production-ready; many still front Go with proxies but it’s not required.
  • GOMEMLIMIT and GOMAXPROCS/automaxprocs are recommended for containerized deployments to respect memory/CPU limits.

Language Design, Error Handling, and Ergonomics

  • Some developers enjoy Go’s explicit error handling and simplicity (“if err != nil” everywhere) and see it as clarity, not noise.
  • Others criticize Go as a “1990s” design: nil handling without option types, verbose checks, weaker type system, lack of modern conveniences, and ergonomics issues like the Header.Get API.
  • There’s broad agreement that Go’s runtime, tooling, and governance are excellent even where the language itself feels limited or unexpressive.