code-conventions
Code Conventions
Opinionated coding conventions for Go, TypeScript/Vue, and Astro projects. Every rule exists because it prevented a real bug or eliminated real friction.
Priority: Clarity > Simplicity > Concision > Maintainability > DRY.
Part 1: Go Conventions
1.1 CLI Framework
Preferred: urfave/cli/v3.
- Use
Destination: &var+Sources: cli.EnvVars("ENV_NAME")for every flag. - One subcommand per package under
cmd/<name>/. - Entry point in
main.gocallsapp.Run().
// Good.
&cli.BoolFlag{
Name: "metrics",
Usage: "Enable Prometheus metrics",
Value: true,
Sources: cli.EnvVars("APP_METRICS"),
Destination: &metricsFlag,
}
// Bad: positional args, no env var source.
app.Action = func(c *cli.Context) error {
host := c.Args().First()
}
1.2 Logger
Preferred: github.com/meysam81/x/logging thin wrapper around zerolog.
- Project wraps in
internal/logger/withtype Logger = zerolog.Logger. - ALL packages receive
*logger.Loggervia constructor injection. - NEVER import
github.com/rs/zerolog/log(the global logger). Onlyinternal/logger/may. - Enforce with
depguardlinter rule.
// Good: DI via constructor.
func NewService(store Store, log *logger.Logger) *Service {
return &Service{store: store, log: log}
}
// Bad: global logger import.
import "github.com/rs/zerolog/log"
func doWork() { log.Info().Msg("bad") }
1.3 Config / Environment
Preferred: caarlos0/env/v11.
- Struct tags:
env:"VAR_NAME" envDefault:"value". Validate()returns[]stringof ALL errors (accumulate, don't fail on first).- Never use
requiredtags — validate manually for better error messages.
type Config struct {
Port int `env:"PORT" envDefault:"8080"`
EncryptionKey string `env:"ENCRYPTION_KEY"`
}
func (c *Config) Validate() (errs []string) {
if c.EncryptionKey == "" {
errs = append(errs, "ENCRYPTION_KEY is required")
}
if c.Port < 1 || c.Port > 65535 {
errs = append(errs, "PORT must be 1-65535")
}
return errs
}
1.4 HTTP Framework
Preferred: chi via github.com/meysam81/x/chimux.
chimux.NewChi()with functional options:WithLoggingMiddleware(),WithMetrics(),WithHealthz(),WithLogger().- Built-in: CleanPath, RealIP, Recoverer (disable with
WithDisable*options). - Structured logging middleware masks sensitive headers automatically.
- Use
r.With()for per-route middleware. Never check HTTP methods inside handlers.
r := chimux.NewChi(
chimux.WithLoggingMiddleware(),
chimux.WithLogger(log),
chimux.WithMetrics(),
chimux.WithHealthz(),
)
r.With(authMW).Get("/api/users", handleUsers)
1.5 Error Handling
NEVER assign errors to _. Every error must be logged, returned, or handled.
This includes rows.Close(), json.Marshal(), result.RowsAffected(), ALL stdlib/lib calls.
// Good.
if err := store.Close(); err != nil {
log.Error().Err(err).Msg("close store")
}
// Bad.
_ = store.Close()
- Wrap errors with context:
fmt.Errorf("load user %s: %w", id, err). - NEVER expose
err.Error()in API responses. Log raw errors internally, return user-friendly messages. - Use an
httperrpackage with constants for all user-facing messages.
// Good: user-friendly error, raw error logged internally.
httperr.WriteError(w, http.StatusNotFound, httperr.DomainNotFound)
// Bad: leaks internal error details.
http.Error(w, err.Error(), 500)
1.6 JSON
Preferred: github.com/goccy/go-json. Never stdlib encoding/json.
writeJSONhelper on the Server struct.- Use
json.NewEncoder(w).Encode()for responses.
import "github.com/goccy/go-json"
func (s *Server) writeJSON(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(data); err != nil {
s.log.Error().Err(err).Msg("failed to encode JSON")
}
}
1.7 Storage / SQL
Preferred: sqlc for query generation, go-migrate for schema migrations.
- Use
sqlc.arg(name)named params. Positional?only for 1-2 simple args. - NEVER use
RETURNING *— explicit column lists only. - Queries in
internal/storage/queries/*.sql, generated code ininternal/db/(NEVER edit generated code). - Migrations in
internal/storage/migrations/XXXXXX_<name>.{up,down}.sql.
-- Good.
-- name: GetUser :one
SELECT id, email, name FROM users WHERE id = sqlc.arg(user_id);
-- Bad: RETURNING *, positional params.
INSERT INTO users (email) VALUES (?) RETURNING *;
1.8 SQLite
Preferred: github.com/meysam81/x/sqlite.
- Build-tag driver split:
mattn/go-sqlite3(CGO),modernc.org/sqlite(pure-Go fallback). - WAL journal mode by default.
MaxOpenConns=1for SQLite.
db, err := sqlite.NewDB(ctx, "app.db",
sqlite.WithJournalMode("wal"),
sqlite.WithConnMaxOpen(1),
)
1.9 Primary Keys
Preferred: TSID (Time-Sorted IDs).
- Internal:
int64. External (API/JWT/URLs): Crockford Base32 string. JSONIDtype auto-marshals int64 to/from Base32 in JSON.pathID(r, "name")to decode URL params.tsid.Encode(id)in tests.
type UserResponse struct {
ID tsid.JSONID `json:"id"` // marshals as "01ARZ3NDEKTSV4RRFFQ69G5FAV"
Name string `json:"name"`
}
1.10 Structs
- NEVER use inline/anonymous structs. Define named types.
- NEVER use
map[string]interface{}ormap[string]any. Define proper structs. - Named types for ALL request/response bodies.
internal/models/for cross-package shared types.
// Good.
type CreateUserRequest struct {
Email string `json:"email"`
Name string `json:"name"`
}
// Bad: inline struct.
json.NewDecoder(r.Body).Decode(&struct {
Email string `json:"email"`
}{})
// Bad: bare map.
data := map[string]interface{}{"email": email}
1.11 Interfaces
- Define narrow interfaces at the call site, not where implemented.
- Accept interfaces, return concrete types.
- Use function types for simple callbacks.
// Good: narrow interface at call site.
type Store interface {
LogAudit(ctx context.Context, entry AuditEntry) error
}
// Bad: fat interface defined alongside implementation.
type UserRepository interface {
Create(...) error
Read(...) error
Update(...) error
Delete(...) error
List(...) error
Search(...) error
// 20 more methods...
}
1.12 Enums
- Go
constwith custom string types. NEVER use DB ENUMs. - Database stores plain strings. Application enforces valid values.
type Role string
const (
RoleOwner Role = "owner"
RoleAdmin Role = "admin"
RoleViewer Role = "viewer"
)
1.13 Goroutines
- No sporadic
go func(). Use structured concurrency. - Preferred:
sync.WaitGroupwithwg.Go(func(){})or a job pool. - Context-aware tickers: always have a
<-ctx.Done()select leg.
// Good: structured, context-aware.
wg.Go(func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
doWork()
case <-ctx.Done():
return
}
}
})
// Bad: fire-and-forget.
go func() {
for range time.Tick(interval) {
doWork()
}
}()
1.14 HTTP Server Hardening
Always set on http.Server:
ReadHeaderTimeout(prevent slowloris)MaxHeaderBytes- Body size limits via
http.MaxBytesReader - Security headers: HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
1.15 HTTP Client
- DRY: centralize in
internal/httpclient/. - ALWAYS use
http.NewRequestWithContext. Never barehttp.NewRequest. context.WithTimeoutfor bounded operations.- Retry logic with exponential backoff.
// Good.
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
// Bad.
req, _ := http.NewRequest("GET", url, nil)
1.16 Crypto
Preferred: github.com/meysam81/x/cryptox.
Cipherinterface withEncrypt(plaintext) / Decrypt(ciphertext).- AES-256-GCM (default), ChaCha20-Poly1305, Argon2id / PBKDF2 password-based.
GenerateKey256()for secure key generation. Alwayscrypto/rand.
1.17 SMTP
Preferred: github.com/meysam81/x/smtpclient.
- Functional options:
WithTimeout(),WithRetry(),WithAuthType(). - TLS/STARTTLS support. Multipart messages with attachments.
- Retry with exponential backoff. Context-aware sending.
1.18 Config Structs & Functional Options
- If
New()takes >2 args, use aConfigstruct. Validate insideNew(). - Functional options pattern:
type Option func(*options),With*()constructors. - Always provide sensible defaults in the constructor.
type Option func(*options)
type options struct {
timeout time.Duration
retries int
}
func WithTimeout(d time.Duration) Option {
return func(o *options) { o.timeout = d }
}
func New(opts ...Option) *Client {
o := &options{timeout: 30 * time.Second, retries: 3} // sensible defaults
for _, opt := range opts {
opt(o)
}
return &Client{opts: o}
}
1.19 Context
- Always accept
ctx context.Contextas first parameter. context.WithTimeoutfor bounded operations.context.WithValuefor request-scoped data with typesafe keys (unexported key type).
1.20 Time
- Default format:
time.RFC3339. - Config intervals as seconds (int). Code-level durations as
time.Duration.
1.21 Control Flow
switchoverif/elsechains when >2 branches. Enforced bygocritic ifElseChain.- Happy path flows straight down. Handle errors immediately with early returns.
// Good.
switch {
case status >= 500:
event = log.Error()
case status >= 400:
event = log.Warn()
default:
event = log.Info()
}
// Bad.
if status >= 500 {
event = log.Error()
} else if status >= 400 {
event = log.Warn()
} else {
event = log.Info()
}
1.22 Testing
- Table-driven tests with
ttloop variable. - Narrow mock interfaces (test-specific, not shared).
httptest.NewRequest+httptest.NewRecorderfor handler tests.synctest.Testfor goroutine tests.t.Helper()on helper functions.
1.23 Structured Logging
- Zerolog structured fields:
.Str(),.Int(),.Err(),.Msg(). - Always include context fields:
user_id,org_id,ipwhere available. - Log durations for operations. Warn for slow queries.
- Log level by status: 5xx → Error, 4xx → Warn, 2xx/3xx → Info.
1.24 DRY
- Grep before creating utilities. Check if the function already exists.
- Extract shared code to
internal/<pkg>/with a focused responsibility. - Anti-example:
extractIPduplicated acrossaudit/middleware.goandratelimit/ratelimit.go.
1.25 Package Naming
- One responsibility per package. Never
util,helper,common,model. - Package name describes what it provides, not what it contains.
- Lowercase only, no underscores, no mixedCaps.
1.26 API Routes
- All user-facing endpoints under
/api/. - Internal endpoints at their own root (
/metrics,/healthz). - Enables clean network policy routing.
1.27 Email Templates
- MJML source templates +
go:generate bunx mjmlto compile to HTML. - Compiled HTML embedded via
//go:embed. - Production email headers: List-Unsubscribe, postal address in footer.
1.28 Graceful Shutdown
signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM).- Soft timeout → hard timeout pattern.
- Drain buffered channels before exit. Close DB connections.
1.29 Observability
Preferred: github.com/meysam81/x/tracing for OpenTelemetry.
- OTLP HTTP export, chi-compatible middleware.
- Auto-shutdown on context cancellation.
- Prometheus metrics via chimux
WithMetrics().
1.30 CSRF
X-CSRF-Tokenheader. Middleware enforcement on mutations.- Token generated server-side, returned in cookie or response body.
1.31 Single Binary
//go:embed distfor SPA static assets.//go:generate sqlc generatefor SQL.//go:generate bunx mjml ...for email templates.- Single binary deployment to scratch container.
Part 2: TypeScript / Vue Conventions
2.1 Build
- Preferred: Vite.
- Production: minify (esbuild),
cssMinify(lightningcss), Brotli compression plugin. - Manual chunks for vendor splitting.
assetsInlineLimit: 4096.
2.2 HTTP Client
- Centralized
kywrapper inlib/api.{js,ts}. NEVER use rawfetch(). - NEVER
import ky from "ky"directly — always through the centralized module. - Auth hooks, CSRF injection, org-id header injection built into the wrapper.
- Enforce with ESLint
no-restricted-importsrule.
// Good: centralized wrapper.
import { api } from "@/lib/api";
const user = await api.get("users/me").json();
// Bad: raw fetch.
const res = await fetch("/api/users/me");
// Bad: direct ky import.
import ky from "ky";
2.3 Validation
- Preferred: Zod for schemas.
- Shared validators in
shared/validation.ts— zero-dependency pure functions. - Centralized
VALIDATION_MSGobject for user-facing messages.
2.4 Design Tokens
3-layer CSS variable system in shared/design-tokens.css:
- L1 Primitives: raw color values (teal, slate, green, amber, red, blue, etc.)
- L2 Semantic: purpose-driven aliases (brand, bg, text, borders, status)
- L3 Component: specific component tokens (buttons, cards, nav, badges)
NEVER hardcode #hex, rgb(), or rgba() in .vue or .astro files.
Both light and dark themes defined in the same token file.
Exceptions: SVG inline attrs, getComputedStyle() fallbacks, color picker inputs.
/* Good: use semantic token. */
.card {
background: var(--color-bg-card);
}
/* Bad: hardcoded color. */
.card {
background: #ffffff;
}
2.5 Layout
.page-container(1200px),--md(1024px),--sm(768px) from shared CSS.- NEVER set
max-widthormargin: 0 autoin scoped styles. - Page headers:
.page-header/.page-title/.page-subtitleglobals.
2.6 Vue Components
<script setup>always. Composition API only.defineProps<{}>()anddefineEmits<{}>()with TypeScript generics.- Named slots for flexibility.
v-iffor conditional rendering.
2.7 State Management
- Preferred: Pinia with Composition API.
defineStore("name", () => {})with explicit return object.ref()for state,computed()for derived values.
export const useAuthStore = defineStore("auth", () => {
const user = ref<User | null>(null);
const isLoggedIn = computed(() => !!user.value);
function logout() {
user.value = null;
}
return { user, isLoggedIn, logout };
});
2.8 Data Fetching
- Preferred: TanStack Vue Query.
- Reactive
queryKeyviacomputed(). SetstaleTimefor caching. - Mutation invalidation to keep data fresh. One composable per domain.
2.9 TypeScript Migration
- Boy scout rule: new files in
.ts, gradually migrate.js. - Shared modules (
shared/) always TypeScript. - Use
defineProps<{}>()generics, notdefineProps({})options syntax.
2.10 Composables
use*prefix. Return reactive refs + functions.- Pattern: validate → set loading → pushUrl → run async function.
export function useDomainTool(opts: ToolOptions) {
const domain = ref("");
const loading = ref(false);
const result = ref(null);
function validate() {
return !!domain.value.trim();
}
async function run() {
if (!validate()) return;
loading.value = true;
try {
result.value = await opts.fetcher(domain.value);
opts.pushUrl?.(domain.value);
} finally {
loading.value = false;
}
}
return { domain, loading, result, validate, run };
}
2.11 Router
- Lazy loading:
() => import('./views/UserView.vue'). - Route meta for title, breadcrumb, required permissions.
- Auth guards. Safe redirect validation (no open redirects).
2.12 CSS
- Scoped styles. CSS custom properties only (from design tokens). No CSS frameworks.
- Responsive via media queries +
clamp()for fluid typography. - Mobile-first approach.
2.13 Shared Data
shared/site.ts+shared/pricing.tsfor DRY constants.- Never hardcode protocol counts, pricing, feature limits in components.
2.14 ESLint
- Vue flat config with recommended rules.
- ky enforcement rules (no-restricted-imports for
fetchand directky). - Prettier compatibility overrides.
2.15 Package Management
bunalways. Nevernpm.- Script name:
"start"(never"dev"). "type": "module"inpackage.json.
2.16 Error States
try/catchwith user-friendly messages. Never expose internal details.- Pattern:
v-if="errorMsg"for conditional error display.
2.17 Forms
v-model+ explicit validation functions.@submit.prevent. Loading state during submission.
Part 3: Astro Conventions
3.1 Framework Setup
- Astro with SSG (
output: "static"). - Content collections for structured data (blog, learn, research).
- MDX for rich content pages. Vue for interactive islands.
3.2 Sitemap
@astrojs/sitemapintegration with XSL stylesheet viaxslUrl.- Produces styled, human-readable XML sitemaps.
3.3 RSS
- Styled RSS feed with XSL stylesheet.
rss.xml.tsendpoint with proper<channel>metadata.
3.4 SEO & Machine-Readable Files
robots.txtas static Astro page.llms.txt— concise site description for LLM crawlers.llms-full.txt.ts— comprehensive version generated from content collections.
3.5 Search
- Pagefind for client-side static search (zero JS bundle cost at build time).
- Custom CSS overrides in
pagefind-overrides.cssfor brand consistency.
3.6 Compression
@playform/compressfor automatic Brotli/gzip compression of all output files.
3.7 Alternate URLs
.md.tsendpoints for machine-readable versions of key pages.- Pricing, tools, compare, and research pages all have
.mdalternates.
3.8 Content Collections
- Explicit
slugfield in frontmatter (not filename-derived). content.config.tswith Zod schemas for validation.- Use
getCollection()andgetEntry()API for type-safe access.
---
title: "My Blog Post"
slug: "my-blog-post" # explicit, not derived from filename
publishDate: 2026-03-15
tags: ["email", "security"]
---
3.9 MDX Components
Reusable components for content pages, exported from components/mdx/index.ts:
CTA— call-to-action blocksCallout— info/warning/tip boxesStepList— numbered step sequencesCodeBlock— syntax-highlighted codeFigure— images with captionsDataTable— structured data displayDashboardShot— product screenshot with frame
3.10 Blog Features
- Table of Contents: auto-generated from headings
- Share buttons: social platform sharing
- Read time: word count-based calculation
- Tags: with dedicated tag index pages (
/blog/tags/[tag]) - Search: Pagefind integration on blog index
3.11 OG Images
- Dynamic generation via
satoriinsrc/og/directory. - Template per content type: blog, learn, tools, compare, research.
- Reuse brand colors from design tokens. Font loading via
fonts.ts.
3.12 Design Token Reuse
- Same
shared/design-tokens.cssused by both Astro and SPA. - Import in Astro's
BaseLayout.astro. Ensures visual consistency.
3.13 Layout System
BaseLayout.astro: HTML skeleton, SEO meta, global styles.- Specialized layouts per content type:
BlogLayout.astro,ToolLayout.astro,LearnLayout.astro,ResearchLayout.astro.
3.14 Vue Islands
- Interactive components rendered as Vue islands.
- Use
client:visible(lazy) orclient:load(eager) directives. - All tools are Vue components with the
DomainToolForm.vue+useDomainTool.tspattern.
3.15 Trailing Slashes
- Enforced in Astro config:
trailingSlash: "always". - All internal links must end with
/.
3.16 Shared Data
shared/site.ts+shared/pricing.tsimported by both Astro and SPA.- Single source of truth for brand facts, protocol counts, pricing.
3.17 Compare Pages
- Data-driven competitor comparison pages.
- TypeScript data files in
src/data/compare/with shared types. - DRY pricing token replacement via utility function.
3.18 Research Pages
- Reusable research components:
StatCard,ProtocolBar,DataHighlight,KeyFindings,MethodologySection. - Data-driven layouts for study results.
3.19 Print Styles
- Dedicated
print.cssfor print-friendly output.
3.20 Snippets
- Code/data snippets in
src/snippets/directory. - Imported into MDX posts to keep content files clean and focused.
Part 4: Project Structure & Tooling
4.1 Linting
- Go:
golangci-lintv2 with strict config.depguardfor import control (block global zerolog).errcheckwithcheck-blank: true.gocritic,gosec,bodyclose,sqlclosecheck,nilerr.- Config format:
version: "2",linters.default: standard, explicitenable/disablelists.
4.2 Pre-commit
gitleaksfor secret detection.commitlintfor conventional commits (feat:,fix:,chore:, etc.).gofmt,go vet,goimportsfor Go formatting.prettierfor frontend formatting.oxlintfor fast JavaScript/TypeScript linting.
4.3 CI Pipeline
golangci-lintGitHub Action (fails only on new issues via--new-from-rev).- Security job:
govulncheck+gosec+trivy fs. - Frontend checks:
eslint+astro check. - Scheduled:
trivy image+gitleaks --history+semgrep.
4.4 Justfile
- Recipe-driven automation (not Makefile).
- Standard recipes:
create-migrate-revision,sec-vuln,sec-secrets,sec-deps,sec-gosec,sec-all.
4.5 Nix
devShellwith all project tools.- Multi-platform support. Reproducible builds.
4.6 Docker
- Multi-stage builds: frontend → mod → backend →
scratch. CGO_ENABLED=0for static binary./datavolume for persistent storage.
4.7 Single Binary Deployment
//go:embed distembeds SPA into Go binary.//go:generate sqlc generatefor DB queries.//go:generate bunx mjml ...for email templates.- Final image is
scratchwith just the binary.
4.8 Boy Scout Rule
- Leave code better than you found it.
- Suggest DRY improvements when you see duplication.
- Don't adhere to broken patterns — fix them.
- But don't over-refactor: only improve code you're actively touching.
Part 5: meysam81/x Library Ecosystem
Preferred library for cross-cutting Go concerns. All packages follow the functional options pattern.
chimux — Chi Router Factory
r := chimux.NewChi(
chimux.WithLoggingMiddleware(),
chimux.WithLogger(log),
chimux.WithMetrics(),
chimux.WithHealthz(),
chimux.WithHealthEndpoint("/health"),
chimux.WithLogAllHeaders(),
)
Opinionated defaults: CleanPath, RealIP, Recoverer enabled. Structured logging: status-based log level (5xx→Error, 4xx→Warn), sensitive header masking (Authorization, Cookie, X-API-Key).
logging — Zerolog Wrapper
type Logger = zerolog.Logger
l := logging.NewLogger(
logging.WithLogLevel("info"),
logging.WithColorsEnabled(true),
logging.WithTimeFormat(time.RFC3339),
)
Type alias, not a wrapper struct. ConsoleWriter to stderr, caller info included.
config — Koanf Config Loader
cfg, err := config.NewConfig(
config.WithYamlConfig("config.yml"),
config.WithEnvPrefix("APP_"),
config.WithDefaults(defaults),
config.WithUnmarshalTo(&appConfig),
)
Layered loading: defaults → JSON → YAML → environment variables. Each layer overrides the previous.
cryptox — Symmetric Encryption
// Cipher interface.
type Cipher interface {
Encrypt(plaintext []byte) ([]byte, error)
Decrypt(ciphertext []byte) ([]byte, error)
}
// AES-256-GCM (default).
cipher, _ := cryptox.NewAESGCM(key)
// ChaCha20-Poly1305.
cipher, _ := cryptox.NewChaCha20(key)
// Password-based (Argon2id + AES-256-GCM).
cipher, _ := cryptox.NewArgon2id(password)
sqlite — SQLite Connection Factory
db, err := sqlite.NewDB(ctx, "app.db",
sqlite.WithJournalMode("wal"),
sqlite.WithConnMaxOpen(1),
)
Build-tag driver split: mattn/go-sqlite3 (CGO) vs modernc.org/sqlite (pure-Go). Automatic file creation if not exists.
smtpclient — SMTP Email Client
client, _ := smtpclient.New(host, port, user, pass,
smtpclient.WithTimeout(30*time.Second),
smtpclient.WithRetry(3, time.Second),
)
err := client.SendEmail(ctx, smtpclient.Email{
From: "noreply@example.com",
To: []string{"user@example.com"},
Subject: "Hello",
HTMLBody: "<h1>Welcome</h1>",
})
tracing — OpenTelemetry
tracer, _ := tracing.NewTracer(ctx, &tracing.TracingConfig{
ServiceName: "my-service",
ServiceVersion: "1.0.0",
Enabled: true,
}, log)
r.Use(tracer.HTTPMiddleware) // chi middleware
Auto-shutdown when context is cancelled. No-op tracer when disabled.
ratelimit — Redis Rate Limiting
Five algorithms, all via atomic Lua scripts:
TokenBucket— allows bursts up to capacityLeakyBucket— enforces smooth constant rateSlidingWindow— rolling window with individual timestampsFixedWindow— discrete non-overlapping windowsDistributedSlidingWindow— multi-node coordination
downloader — HTTP File Download
Parallel chunked downloads, resumable transfers, SHA256 verification, exponential backoff retry. Automatic strategy selection based on server capabilities.
httputils — stdlib HTTP Helpers
Logging middleware for net/http (use when not using chi/chimux).
Universal Principles
These apply across all languages and frameworks:
- DRY: Grep before creating utilities. Extract shared code. Never duplicate logic.
- 12-Factor: Environment-based config. Stateless processes. Explicit dependencies.
- Simplicity First: Every change as simple as possible. Minimal code impact.
- No Laziness: Find root causes. No temporary fixes. Staff-engineer standards.
- Security: Never expose internal errors. Validate at boundaries. Use
crypto/rand. - Backend-Driven Logic: ALL business logic in the backend API. Frontend renders decisions, never makes them. Verdicts, scores, permissions — computed server-side.
- Boy Scout: Leave code better than found. Fix patterns, don't perpetuate broken ones.
- Confirm Dependencies: Before adding ANY dependency, ask: can we build it in-house? Must be production-ready, minimal, actively maintained.
- No Estimates: Don't predict how long tasks will take. Focus on what needs doing.
- Verify Before Done: Never mark a task complete without proving it works. Run tests, check logs, demonstrate correctness.
More from meysam81/cc
seo-social
Generate platform-specific social media posts from a blog draft. Covers X, Bluesky, Mastodon, LinkedIn, Reddit, Patreon, and Buy Me a Coffee in 3 tiers (short-form, long-form, patronage).
3seo-backlink-outreach
Analyze site pages, discover backlink prospects via SERP analysis and web search, and generate A/B outreach email templates with spintax and follow-up sequences.
3seo-review
Audit a blog post draft against SEO best practices with a 100-point scoring rubric. Identifies specific issues and provides fix recommendations.
2seo-research
Generate a deep research prompt for Claude.ai to gather facts, stats, expert quotes, and competitor analysis for a blog post topic
2seo-optimize
Post-publish validation using DataForSEO tools. Checks Lighthouse scores, on-page SEO verification, ranking position, and AI search visibility.
2seo-write
Write a complete SEO-optimized blog post from an approved outline, research brief, and brand voice. Produces a publish-ready draft with schema markup.
2