codeflash-agent/plugin/languages/go/references/library-replacement.md
Kevin Turcios 361bb899e2
Move Go overlay to plugin/languages/go/ (#13)
* Move Go plugin overlay from languages/go/ to plugin/languages/go/

Aligns Go with the Java/Python/JavaScript convention where all language
overlays live under plugin/languages/<lang>/. The Makefile already
discovers from plugin/languages/* so Go is now included in builds.

* Remove accidental read-tracker changes

* Ignore .codeflash/observability/ in gitignore
2026-04-14 19:14:57 -05:00

2.9 KiB

Library Replacement Guide — Go

When to Consider

All three conditions must hold:

  1. Profiling evidence: Library accounts for >15% of cumtime
  2. Plateau evidence: Domain agent tried to reduce calls, cache results — still plateaued
  3. Narrow usage surface: Codebase uses a small fraction of the library's API

Common Replacements

Library Use case stdlib alternative
encoding/json (reflect-based) JSON marshaling Code-generated: easyjson, sonic, go-json
fmt.Sprintf String formatting strconv + strings.Builder
regexp (for simple patterns) Pattern matching strings.Contains/HasPrefix/Cut
net/http (full server) Simple routing Direct http.HandlerFunc (avoid framework overhead)
pkg/errors Error wrapping fmt.Errorf("%w", err) (Go 1.13+)
logrus/zap (for simple cases) Logging log/slog (Go 1.21+)
go-yaml YAML parsing Consider if JSON or TOML would work instead
CGo library C bindings Pure Go alternative (check awesome-go)
net/http (high concurrency) HTTP server cloudwego/netpoll (epoll-based, minimal GC) or tidwall/evio (event loop)
net (DNS resolution) DNS lookup Custom resolver with caching (Go doesn't cache DNS by default)
Manual TLS config TLS performance Session tickets + ECDSA certs + AES-GCM (58% faster in Go 1.25)

Assessment Process

Step 1: Audit usage surface

# What does the codebase import from the library?
grep -rn 'import.*"library"' --include='*.go' . | grep -v vendor
grep -rn 'library\.' --include='*.go' . | grep -v _test.go | grep -v vendor | sort -u

Step 2: Classify each usage

  • Can stdlib handle this?
  • Does the library provide safety guarantees the replacement must maintain?
  • Are there edge cases the library handles that a simple replacement would miss?

Step 3: Implement replacement

  • One function at a time
  • Benchmark each replacement independently
  • Verify correctness with existing tests

Step 4: Verify

go test ./...
go test -race -short ./...
go vet ./...
benchstat old.txt new.txt

encoding/json Replacement (most common)

encoding/json uses reflect and allocates heavily. For hot paths:

Option A: Code-generated marshaler

# Install easyjson
go install github.com/mailru/easyjson/...@latest

# Generate marshalers
easyjson -all pkg/model/types.go

Option B: Manual marshaling for critical paths

// Instead of json.Marshal(obj), write directly:
func (o *Obj) MarshalJSON() ([]byte, error) {
    var buf bytes.Buffer
    buf.WriteString(`{"name":"`)
    buf.WriteString(o.Name)
    buf.WriteString(`","count":`)
    buf.WriteString(strconv.Itoa(o.Count))
    buf.WriteByte('}')
    return buf.Bytes(), nil
}

Option C: Use a faster JSON library

import "github.com/goccy/go-json"
// Drop-in replacement for encoding/json
data, err := json.Marshal(obj)