- Published on
Modern Go in 2026 — Go 1.24 / Echo / Gin / Fiber / Huma / Encore / sqlc / Templ / Bubble Tea Deep-Dive
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Prologue — Why Go again, in 2026
- 1 · Go 1.22 (Feb 2024) — End of the for-loop trap, range over int
- 2 · Go 1.23 (Aug 2024) — range over func, iterators arrive officially
- 3 · Go 1.24 (Feb 2025) — Generics maturity, Tool deps, Weak pointers, omitzero
- 4 · Web frameworks — Gin / Echo / Fiber / Chi / Huma
- 5 · Database — sqlc / ent / GORM / Bun
- 6 · Encore — A backend platform that loves Go
- 7 · Templ + htmx — Fullstack without JS
- 8 · Charmbracelet — The TUI renaissance of Bubble Tea, Lipgloss, Glamour
- 9 · Cobra — The CLI standard
- 10 · Wails — Go + webview desktop
- 11 · golangci-lint v2 (2024) — Configuration rewrite
- 12 · Pulumi Go / gRPC-Go / Wasmtime-Go — Other essentials
- 13 · Korea / Japan — Toss / Kakao / Mercari / CyberAgent / LINE Yahoo
- 14 · Who should pick Go — Microservices / CLI / DevOps / Systems
- 15 · References
Prologue — Why Go again, in 2026
Go was released in 2009. In May 2026 it turns sixteen. The biggest strength across that decade has been refusing to lose its identity as a "boring language." While the JavaScript camp swapped build tools three times a year, while Rust polished borrow checking, while Python redrew its typing system annually, Go held to the 1.0 compatibility promise and only piled on small improvements. But if you look at Go in spring 2026, the landscape that small improvements have built is anything but small.
There are three inflection points.
First, language maturity. Go 1.22 in February 2024 ended the for-loop variable capture trap. Go 1.23 in August 2024 admitted range-over-func as a formal feature. Go 1.24 in February 2025 made generics into a tool you can confidently reach for in production. Alongside, the tool directive ended the tools.go trick, and weak.Pointer changed how caches are built.
Second, ecosystem differentiation. There was once a consensus that "just use the standard net/http." Today Gin still leads, but Echo, Fiber, Chi and Huma each hold meaningful ground. ORMs no longer mean GORM by default; sqlc (query-first), ent (schema-first), GORM (learning-curve) and Bun (query builder) split the field four ways.
Third, new superpowers. Templ arrived and, paired with htmx, opened a "fullstack without JS" path. Encore opened a new category — "Go-flavored backend platform." Charmbracelet's Bubble Tea, Lipgloss, Glamour drove a terminal-UI renaissance. Wails hardened the case for Go + webview desktop apps as an Electron alternative.
This piece pulls those three currents together. What Go 1.22 through 1.24 finished, who today's champions are in web, database, fullstack, CLI and desktop, how the big East Asian tech companies actually use Go, and when you should and should not pick Go for a fresh 2026 project.
All numbers and versions are as of May 16, 2026. Go itself moves slowly, but the library ecosystem moves fast. The structural decision frames are written to outlive the numbers.
1 · Go 1.22 (Feb 2024) — End of the for-loop trap, range over int
The single most common newcomer trap was for i := range slice { go func() { use(i) }() }. Every goroutine captured the last value of i. Go 1.22 in February 2024 changed the semantics. Each iteration now creates a fresh variable. It took the Go team a full decade to ship this because they would not break the compatibility promise. The new behavior is activated by the go 1.22 line in go.mod, so older modules retain the old semantics.
The same release added range over int. for i := range 10 is equivalent to for i := 0; i < 10; i++. It looks trivial, but it visibly improves the readability of tests and benchmarks.
// Before Go 1.22 — every iteration captures the same i
for i := range items {
wg.Add(1)
go func() {
defer wg.Done()
process(items[i]) // dangerous: i is shared by all goroutines
}()
}
// Go 1.22+ — each iteration has a fresh i
for i := range items {
wg.Add(1)
go func() {
defer wg.Done()
process(items[i]) // safe
}()
}
// range over int (Go 1.22+)
for i := range 10 {
fmt.Println(i) // 0..9
}
net/http's ServeMux also gained first-class method-and-pattern matching in 1.22. mux.HandleFunc("GET /users/{id}", handler) works without chi or gin. For simple APIs you can start without an external router dependency.
2 · Go 1.23 (Aug 2024) — range over func, iterators arrive officially
The signature change in Go 1.23, released in August 2024, was range over func. If a function has the shape func(yield func(T) bool), you can iterate that function with for v := range f. It means collection libraries can finally share a common API shape.
// Iterator pattern in Go 1.23+
func Filter[T any](s []T, pred func(T) bool) func(yield func(T) bool) {
return func(yield func(T) bool) {
for _, v := range s {
if !pred(v) {
continue
}
if !yield(v) {
return
}
}
}
}
// Usage
for v := range Filter(nums, func(n int) bool { return n%2 == 0 }) {
fmt.Println(v)
}
The standard library filled out iter, slices, maps. slices.All, maps.Keys, maps.Values all return iterators now. Like the Iterator trait in Rust or generators in JavaScript, Go finally has a standard vocabulary for traversing collections.
The structs package introduced the HostLayout type that explicitly guarantees struct layout for cgo and syscall code. It cleans up padding hazards that have long bitten systems programmers.
Because of the compatibility promise, every new feature is opt-in. Only modules with go 1.23 in go.mod see the new behaviors. This is Go's biggest asset — code written sixteen years ago still builds.
3 · Go 1.24 (Feb 2025) — Generics maturity, Tool deps, Weak pointers, omitzero
Go 1.24 shipped in February 2025. It is widely considered the most significant release since 1.18 first introduced generics. Four changes matter most.
(1) Generic type aliases. From 1.24 you can attach type parameters to type aliases, e.g. type Set[T comparable] = map[T]struct{}. Before 1.23 you could not write generic aliases, and the boilerplate that piled up across libraries was visible.
(2) Tool directives. go.mod now accepts a tool directive. It ends the long-standing tools.go workaround where you kept build tools alive via blank imports.
// Go 1.24 — go.mod
module example.com/myapp
go 1.24
require (
github.com/spf13/cobra v1.10.0
)
tool (
github.com/golangci/golangci-lint/v2/cmd/golangci-lint
github.com/sqlc-dev/sqlc/cmd/sqlc
)
Now go tool golangci-lint run just works, and you do not have to go install separately. CI pipelines get cleaner.
(3) Weak pointers (weak.Pointer). Big news for cache implementations. Useful when you want to cache a large value but let the GC reclaim it under memory pressure. Conceptually similar to Java's WeakReference or Rust's Weak<T>.
import "weak"
type Cache struct {
mu sync.Mutex
m map[string]weak.Pointer[Bitmap]
}
func (c *Cache) Get(key string) *Bitmap {
c.mu.Lock()
defer c.mu.Unlock()
if wp, ok := c.m[key]; ok {
if b := wp.Value(); b != nil {
return b
}
}
b := load(key)
c.m[key] = weak.Make(b)
return b
}
(4) omitzero JSON tag. A long-standing pain point — omitempty treats zero values as empty. So 0 for int, false for bool, the zero time.Time all get dropped from serialization. That is rarely what you want. 1.24's omitzero drops only when the value is exactly the zero value. More precise.
type Event struct {
Name string `json:"name"`
Count int `json:"count,omitempty"` // dropped when 0
Active bool `json:"active,omitempty"` // dropped when false
StartAt time.Time `json:"start_at,omitzero"` // dropped only at zero time
}
Beyond these, runtime/trace got cheaper, FIPS 140-3 certified crypto modules landed, and crypto/mlkem (post-quantum KEM) joined the standard library. That PQC is now in Go's stdlib is striking.
1.24 is "the release that finally made 1.18's generics worth using." Versions 1.18 through 1.20 had enough usability issues that mostly only library authors used generics. From 1.24, ordinary application code uses generics without hesitation.
4 · Web frameworks — Gin / Echo / Fiber / Chi / Huma
In spring 2026, the Go web framework market is "Gin in the lead plus a four-way fight." The table below is an impression, not absolute market share.
| Framework | Stars | Philosophy | Strength |
|---|---|---|---|
| Gin | ~84k | Fast and familiar | Most examples, blogs, middleware |
| Echo | ~32k | Close to standard | Clean API, well-curated docs |
| Fiber | ~36k | Mimics Express | fasthttp-based, friendly to JS folks |
| Chi | ~19k | Thin wrapper over net/http | Standard-compatible, small and solid |
| Huma | ~3.5k | OpenAPI-first | Handlers generated from schema |
Gin — The most-used framework. The reason is simple. When you search, you get the most answers, and there is the most middleware. The downside is that it strays slightly from net/http patterns and uses its own gin.Context. If you start a new project in 2026 and the team is not deeply familiar with Go, Gin is the safest bet.
// Gin
r := gin.Default()
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(200, gin.H{"id": id})
})
r.Run(":8080")
Echo — Nearly the same brand recognition as Gin. The API is slightly cleaner by most accounts. Middleware authoring is intuitive, the documentation is well-organized. WebSocket, HTTP/2 and gRPC are smooth too.
// Echo
e := echo.New()
e.GET("/users/:id", func(c echo.Context) error {
id := c.Param("id")
return c.JSON(200, map[string]string{"id": id})
})
e.Logger.Fatal(e.Start(":8080"))
Fiber — An API that copies Express.js. Built on fasthttp, so it benchmarks fast. But fasthttp is not net/http, so you cannot use some standard middleware, and HTTP/2 support is weaker. Popular when JS developers migrate to Go because the API feels familiar.
// Fiber
app := fiber.New()
app.Get("/users/:id", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"id": c.Params("id")})
})
app.Listen(":8080")
Chi — A thin router on top of net/http. Spiritual successor to the gorilla/mux era. Small, standard-compatible, with middleware that stays light yet powerful. Suits microservices better than monoliths. Even after Go 1.22's ServeMux landed, Chi remains attractive thanks to its rich middleware and sub-router patterns.
// Chi
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Get("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
w.Write([]byte(id))
})
http.ListenAndServe(":8080", r)
Huma — A framework that treats OpenAPI as a first-class citizen. It infers the OpenAPI schema from handler function types and tags. Notably, it can sit on top of Chi, Gin, Echo or Fiber. You get auto-generated API docs while validation, serialization and routing are all handled.
// Huma
type GetUserInput struct {
ID string `path:"id" doc:"User ID"`
}
type GetUserOutput struct {
Body struct {
ID string `json:"id"`
Name string `json:"name"`
}
}
api := huma.New("My API", "1.0.0")
huma.Get(api, "/users/{id}", func(ctx context.Context, in *GetUserInput) (*GetUserOutput, error) {
out := &GetUserOutput{}
out.Body.ID = in.ID
out.Body.Name = "Alice"
return out, nil
})
Which one to pick — If your new team has few Go veterans, Gin. If you want cleanliness, Echo. If you have a lot of JS migrants, Fiber (knowing the standard-middleware constraint). If you want to stay close to standard, Chi. If schema-first matters, Huma.
5 · Database — sqlc / ent / GORM / Bun
The database tool choice is the second-largest debate inside Go teams. Four paths exist.
sqlc — code generation from queries You write SQL by hand. sqlc reads that SQL and generates type-safe Go functions. It is not an ORM. The "SQL-first" approach.
-- queries/users.sql
-- name: GetUser :one
SELECT id, name, email FROM users WHERE id = $1;
-- name: ListUsers :many
SELECT id, name, email FROM users ORDER BY id;
sqlc then generates:
// generated code
type GetUserRow struct {
ID int64
Name string
Email string
}
func (q *Queries) GetUser(ctx context.Context, id int64) (GetUserRow, error) {
row := q.db.QueryRowContext(ctx, getUser, id)
var i GetUserRow
err := row.Scan(&i.ID, &i.Name, &i.Email)
return i, err
}
You preserve the SQL as written, with type safety from codegen. Migrations stay in plain SQL, which DBAs can read. The downside is that dynamic queries are awkward — the approach struggles when one search screen has many optional conditions.
ent — schema-first ORM (Meta) A graph-based ORM from Facebook (now Meta). You declare the schema in Go code, and ent generates migrations, query builders, and relationship loaders.
// schema/user.go
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("name"),
field.String("email").Unique(),
}
}
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("posts", Post.Type),
}
}
// Usage
user, err := client.User.
Create().
SetName("Alice").
SetEmail("alice@example.com").
Save(ctx)
posts, err := user.QueryPosts().All(ctx)
The generated API is exceptionally type-safe. It excels in domains with many complex relationships. Steeper learning curve than sqlc.
GORM — the most-used ORM A dynamic ORM influenced by Rails' ActiveRecord. The most examples and tutorials. But performance overhead and magic are real downsides.
type User struct {
gorm.Model
Name string
Email string `gorm:"unique"`
}
db.AutoMigrate(&User{})
db.Create(&User{Name: "Alice", Email: "alice@example.com"})
var user User
db.First(&user, 1)
Good for fast prototyping. Many teams move to sqlc or ent once production traffic is real.
Bun — query builder The successor to go-pg. A query builder that stays close to SQL. Not an ORM, a builder, so explicitness is high.
err := db.NewSelect().
Model(&users).
Where("active = ?", true).
OrderExpr("id ASC").
Limit(10).
Scan(ctx)
Which one to pick — If the team is strong in SQL and wants control, sqlc. For graph-shaped domains (social, multi-tenant SaaS), ent. For fast prototyping, GORM. If you prefer staying close to SQL but want the builder pattern, Bun. The 2026 trend is sqlc and ent eating into GORM's share.
6 · Encore — A backend platform that loves Go
Encore is a tool that redefined a category between 2024 and 2025. It bundles "a backend framework for Go + cloud deployment + automatic infrastructure code." Reading the code makes it obvious what kind of tool Encore is.
//encore:service
type Service struct {
db *sqldb.Database
}
func initService() (*Service, error) {
db := sqldb.NewDatabase("users", sqldb.DatabaseConfig{
Migrations: "./migrations",
})
return &Service{db: db}, nil
}
//encore:api public method=GET path=/users/:id
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
var u User
err := s.db.QueryRow(ctx, "SELECT id, name FROM users WHERE id = $1", id).
Scan(&u.ID, &u.Name)
if err != nil {
return nil, err
}
return &u, nil
}
A single //encore:api comment defines an endpoint. The Encore CLI parses those comments statically and auto-generates the OpenAPI schema, client SDKs, tracing setup, IAM rules, and migrations. encore run spins up a local environment that boots Postgres alongside. encore deploy deploys your own infrastructure to GCP or AWS.
The pros are clear — backend setup time approaches zero. Inter-service calls are type-safe RPCs. Tracing, logging, monitoring are defaults.
The cons are clear too — Encore enforces its own runtime. It is compatible with general Go projects, but escaping Encore is work. And there is some cloud lock-in.
Encore is "Vercel for Go." Attractive to small teams and startups. A burden if a large company is locked into its own Kubernetes.
7 · Templ + htmx — Fullstack without JS
In spring 2025 the hottest combination in the Go community was Templ + htmx. The intent — "interactive web apps without a JS build toolchain."
Templ is a type-safe HTML templating engine. You write .templ files and templ generate produces Go code. Static analysis is possible, and components are functions.
// hello.templ
package main
templ Hello(name string) {
<div class="greeting">
<h1>Hello, { name }!</h1>
<p>It is { time.Now().Format("2006-01-02") }</p>
</div>
}
// Usage
func handler(w http.ResponseWriter, r *http.Request) {
Hello("Alice").Render(r.Context(), w)
}
Safer than html/template, faster, with better IDE support.
htmx is a library that drives AJAX, WebSocket and SSE from HTML attributes. JS payload of about 13 KB. The core idea — express every interaction as an exchange of HTML fragments.
<button hx-post="/like/123" hx-swap="outerHTML">Like</button>
The server takes the POST to /like/123 and returns a fresh fragment of HTML. htmx slots it into the DOM. Partial updates without SPA complexity.
The meaning of a Go + Templ + htmx stack is clear — a backend engineer who does not know React can write a fullstack. No Webpack, no Vite, no NPM. The downside is that very complex interactions (real-time collaborative editors, 3D rendering) are out of reach.
// Echo + Templ + htmx
e := echo.New()
e.GET("/", func(c echo.Context) error {
return Hello("World").Render(c.Request().Context(), c.Response())
})
e.POST("/like/:id", func(c echo.Context) error {
id := c.Param("id")
return LikeButton(id, true).Render(c.Request().Context(), c.Response())
})
If you are building a side project or an internal admin in 2026, this stack is worth serious consideration. Hugo-style sites, SaaS admins and blog builders get put together very quickly with it.
8 · Charmbracelet — The TUI renaissance of Bubble Tea, Lipgloss, Glamour
Charmbracelet is the company that drove the mid-2020s terminal-UI renaissance. Their library set has effectively become the standard for Go TUIs.
Bubble Tea — A TUI framework based on the Elm architecture. Three functions form the trio: Model, Update, View.
type model struct {
counter int
}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "+":
m.counter++
case "-":
m.counter--
case "q":
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
return fmt.Sprintf("Counter: %d\n[+/-] adjust, [q] quit\n", m.counter)
}
func main() {
tea.NewProgram(model{}).Run()
}
State transitions are explicit, testing is feasible, and composition feels natural. Some interactive screens in GitHub CLI (gh), glow (markdown viewer), and the lazygit family all sit inside Bubble Tea's gravity.
Lipgloss — A style library inspired by CSS. Box model, padding, borders, colors.
style := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FAFAFA")).
Background(lipgloss.Color("#7D56F4")).
Padding(1, 2).
Border(lipgloss.RoundedBorder())
fmt.Println(style.Render("Hello, World!"))
Glamour — A library that renders markdown beautifully in the terminal. AI CLI tools use it almost as a standard when displaying model responses.
Wish — A library to build SSH servers in Go. You can do demos like "ssh chess.example.com" to play chess.
The Charmbracelet ecosystem created a sentiment that "terminals are fun again." In the AI CLI era, the value of this ecosystem has only grown.
9 · Cobra — The CLI standard
When building a Go CLI, the de facto standard is Cobra. Kubernetes, Hugo, Helm, GitHub CLI are all built on Cobra. Commands, subcommands, flags, completion — all in a consistent model.
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "An example CLI",
}
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Run the server",
Run: func(cmd *cobra.Command, args []string) {
port, _ := cmd.Flags().GetInt("port")
fmt.Printf("Serving on :%d\n", port)
},
}
func init() {
serveCmd.Flags().IntP("port", "p", 8080, "Port to listen on")
rootCmd.AddCommand(serveCmd)
}
func main() {
rootCmd.Execute()
}
The sister library Viper handles configuration (env, JSON, YAML, TOML, etcd, Consul) — used together with Cobra frequently.
There is an alternative in urfave/cli. Slightly different API, more terse, but not as widespread as Cobra. In 2026 new CLIs start from Cobra almost universally.
10 · Wails — Go + webview desktop
For people who find Electron's weight too much, Wails is an attractive alternative. Go runs the backend, the system webview (WebKit on macOS, WebView2 on Windows, WebKitGTK on Linux) handles the front. Result binaries are dramatically smaller than Electron — tens of megabytes.
// app.go
type App struct {
ctx context.Context
}
func (a *App) Greet(name string) string {
return "Hello " + name
}
func main() {
wails.Run(&options.App{
Title: "MyApp",
Width: 1024,
Height: 768,
Bind: []interface{}{&App{}},
})
}
For the front you can use React, Vue, Svelte, anything. Go functions are callable from JS. Suits small desktop utilities, markdown editors, GUIs for local databases, minimal IDEs.
The downside is per-OS webview differences. The subtle rendering gaps between Safari, Chromium and Edge demand attention. Still, not having to bundle 100+ MB of Chromium with Electron is a huge gain.
There is also Fyne (pure Go GUI) as an alternative. It paints directly, no webview. Limited mobile support too. But design freedom is lower.
11 · golangci-lint v2 (2024) — Configuration rewrite
The default Go linter, golangci-lint, released v2 in 2024. The biggest change is the rewrite of its configuration file.
v1 carried ten years of accumulated options in a messy heap. v2 cleanly redefines the structure.
# .golangci.yml — v2
version: "2"
run:
timeout: 5m
go: "1.24"
linters:
default: standard
enable:
- errcheck
- govet
- staticcheck
- revive
- gosec
- bodyclose
- errorlint
disable:
- lll
linters-settings:
revive:
rules:
- name: exported
- name: unused-parameter
formatters:
enable:
- gofumpt
- goimports
default: standard activates a best-practice bundle in one line. Formatters (gofumpt, goimports) are separated from linters as their own category. Migration from v1 to v2 is mostly automatic via golangci-lint migrate.
In CI the standard pattern is:
# .github/workflows/lint.yml
name: lint
on: [push, pull_request]
jobs:
golangci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: "1.24"
- uses: golangci/golangci-lint-action@v7
with:
version: v2.0
Combined with Go 1.24's tool directive, go tool golangci-lint run is enough. Separate installation is unnecessary.
12 · Pulumi Go / gRPC-Go / Wasmtime-Go — Other essentials
Pulumi Go — A tool that writes IaC in a real programming language. Terraform stuck with HCL, its own DSL. Pulumi lets you write TypeScript, Python, Go, C#. What appeals to Go users is type safety and the standard tool chain.
// main.go
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
bucket, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{
Acl: pulumi.String("private"),
})
if err != nil {
return err
}
ctx.Export("bucketName", bucket.ID())
return nil
})
}
pulumi up and you have a bucket on AWS. The learning curve is steeper than Terraform, but when managing large infrastructure the power of abstraction shines.
gRPC-Go — Google's RPC framework. Generates Go code from proto3 definitions. The standard for inter-microservice calls. Multiplexing, streaming and metadata over HTTP/2.
// user.proto
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
rpc StreamEvents(EventRequest) returns (stream Event);
}
You generate Go code with protoc, then fill in server and client. Connect-Go (from Buf) has emerged as an alternative that adds HTTP compatibility to gRPC. Callable from the browser as-is.
Wasmtime-Go — Call Bytecode Alliance's WebAssembly runtime from Go. Useful when you need a plugin system that isolates user code. The pattern of WASM filters in proxies like Envoy and Linkerd has grown too.
import "github.com/bytecodealliance/wasmtime-go/v22"
engine := wasmtime.NewEngine()
module, _ := wasmtime.NewModuleFromFile(engine, "hello.wasm")
store := wasmtime.NewStore(engine)
instance, _ := wasmtime.NewInstance(store, module, nil)
run := instance.GetExport(store, "run").Func()
result, _ := run.Call(store)
fmt.Println(result)
One more tool to mention is the NATS Go client. NATS is lightweight messaging written in Go. Lighter and easier to operate than Kafka. Attractive for inter-microservice pub/sub and request/reply.
13 · Korea / Japan — Toss / Kakao / Mercari / CyberAgent / LINE Yahoo
Toss
The fintech most aggressively using Go in Korea. As they moved to a microservices era, some services were rewritten in Go. The tech blog (toss.tech) regularly publishes Go-related posts — gRPC-based internal communication, Go workloads on Kubernetes, latency tuning on payment processing. Kotlin and the JVM remain main, but the pattern of "Go embedded in ultra-low-latency core payment paths" is real.
Kakao Job postings for Go appear continuously at Kakao and Kakao Enterprise. Internal cloud components, CI/CD tooling, and operational automation use Go heavily. Kubernetes operations experience and Go are often paired in hiring.
Mercari The most famous Go company in Japan. The microservices architecture is almost entirely written in Go. The Mercari engineering blog is overwhelmingly Go-heavy — gRPC, Kubernetes, distributed tracing, performance tuning. Reportedly an internal "Go committee" sets standards.
CyberAgent A Japanese ad, gaming and media conglomerate. ABEMA, AmebaTV and game backends use Go. Their subsidiary AbemaTV uses Go extensively for live broadcast infrastructure. A regular sponsor of Go Conference Tokyo.
LINE Yahoo A massive merged company from LINE and Yahoo Japan. LINE-era engineering used Go heavily, and Yahoo Japan, once Java-centric, also increased Go adoption. Reports indicate Go's role grew further during post-merger infrastructure consolidation. Internal messaging, search and ad backends include Go components.
A common pattern across the large East Asian tech companies — Go is the default language of "microservices + Kubernetes + gRPC." It coexists with Java/Kotlin, but has cemented its position in "ultra-low-latency backends" and "devops and platform tooling."
14 · Who should pick Go — Microservices / CLI / DevOps / Systems
At the end of a long piece, a short decision frame.
When Go fits.
- Microservices backend — Fast builds, small binaries, explicit concurrency. Combined with gRPC, a standard architecture.
- CLI / DevOps tooling — A single static binary and you are done. It is no accident that Kubernetes, Terraform, Docker, Hugo and Cobra are all Go.
- Network proxies / infrastructure services — Caddy, Traefik and Envoy (C++) territory. Concurrency and memory efficiency.
- Core components of data pipelines — Vector, Bento, NATS. Not as fast as Rust, but fast enough and far easier to learn.
- JS-free fullstack internal tools — Templ + htmx stack.
- Terminal tooling — Bubble Tea ecosystem.
When Go does not fit.
- Data science / ML model training — Python and Julia dominate. Go shows up only in some ML inference serving.
- The lowest layer of systems programming — Kernels, embedded, real-time. Rust and C are better. The GC is the reason.
- Complex domain models — When algebraic data types, pattern matching and sum types are essential, reach for Rust, Scala, Haskell or OCaml.
- Simple scripts — The compile-build cycle is overhead. Python, Bash and JavaScript are faster.
- High-performance game engines — GC pauses hurt.
Language selection decision tree.
- "Microservices backend?" → Go
- "DevOps tool as a single binary?" → Go
- "Type-safe ORM for a SaaS backend?" → Go (ent) or TypeScript (Drizzle)
- "JS-free internal fullstack tool?" → Go + Templ + htmx
- "AI agent harness?" → Go is a fine pick; Python and TypeScript also active
- "Real-time game server?" → Rust and C++ first; Go second
- "Numerical computing?" → Python, Julia, Rust
Go at sixteen means "boring has been validated." While other languages added new syntax every year, Go added small improvements, and the result in 2026 is the most stable and most predictable option. Many observers expect 1.24's generics maturity to be the last big change. After that comes a real era of "a huge standard library and a stable tool chain."
15 · References
- Go 1.24 Release Notes — go.dev (2025-02)
- Go 1.23 Release Notes — go.dev (2024-08)
- Go 1.22 Release Notes — go.dev (2024-02)
- Go Blog — Range over Function Types
- Go Blog — Type Aliases with Type Parameters in 1.24
- Go Blog — Weak Pointers
- Gin GitHub
- Echo Framework
- Fiber Framework
- Chi Router
- Huma Framework
- sqlc — Generate type-safe Go from SQL
- ent — Entity Framework for Go
- GORM — The fantastic ORM
- Bun — SQL-first Golang ORM
- Encore — Backend Platform for Go
- Templ — HTML templating for Go
- htmx Documentation
- Charmbracelet — Bubble Tea
- Charmbracelet — Lipgloss
- Charmbracelet — Glamour
- Cobra — CLI Framework
- Wails — Go + Web Frontend Desktop Apps
- golangci-lint v2 Migration Guide
- Pulumi Go Documentation
- gRPC-Go
- Connect-Go — Better gRPC for browsers and servers
- Wasmtime-Go
- Mercari Engineering Blog
- Toss Tech Blog
- CyberAgent Developers Blog
- LINE Yahoo Engineering Blog