

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Golang Best Practices78## Go Version9- Code can use Go 1.24 features and improvements10- Reference:11- Key enhancements to leverage:12 - Release notes: @https://tip.golang.org/doc/go1.2413 - Generic type aliases (`type JSONMap[T any] = map[string]T`)14 - New `AddCleanup` and weak references for resource management15 - Improved JSON handling with `omitzero` tag16 - New cryptography packages from x/crypto17 - Testing improvements with `b.Loop()` and test analyzers18 - `os.Root` for filesystem sandboxing19 - Tool dependency management with `go get -tool`20 - Optimized map implementation for faster lookups2122## Language Features23- Use built-in functions `min`, `max`, and `clear` (Go 1.21+)24 - `min(x, y)` and `max(x, y)` to get smaller/larger of two values25 - `clear(m)` to empty maps or slices in one call26- Take advantage of improved generic type inference (Go 1.21+)27 - Let compiler infer type arguments when possible28 - Write clear function signatures to help type inference29- Benefit from fixed loop variable capture (Go 1.22+)30 - Each iteration now has its own copy of variables31 - No need for manual variable capture in loops with goroutines32- Use enhanced range loops:33 - Range over integers directly: `for i := range 10 { ... }` (Go 1.22+)34 - Range over iterator functions (Go 1.23+)35- Use generic type aliases for API clarity (Go 1.24)3637## Standard Library Enhancements38- Use the `slices` package (Go 1.21+) for operations:39 - `slices.Index`, `slices.Contains`, `slices.Clone`, `slices.Compare`40 - `slices.Concat` (Go 1.22+) to concatenate multiple slices41- Use the `maps` package (Go 1.21+) for map operations:42 - `maps.Keys(m)` to get a slice of map keys43 - `maps.Clone(m)` to copy a map44- Leverage the `cmp` package (Go 1.21+) for comparisons45- Adopt `log/slog` for structured logging (Go 1.21+)46- Use `math/rand/v2` for random data generation (Go 1.22+)47- Utilize enhanced HTTP routing with new `ServeMux` patterns (Go 1.22+)48- Use `database/sql.Null[T]` for nullable fields (Go 1.22+)49- Use JSON struct tags effectively, including `omitzero` (Go 1.24)50- Prefer standard library crypto packages including new ones (Go 1.24)5152## Project Structure53- Set appropriate Go version in go.mod to enable new compiler checks54- Use `go mod tidy -diff` (Go 1.23+) to preview dependency changes55- `main.go` is reserved exclusively for application entry point56- All internal packages must reside under `internal/` directory57- Public packages should be placed in `pkg/` directory58- Group related functionality into coherent packages59- Use `cmd/` directory for multiple entry points60- Place test files next to the code they test with `_test.go` suffix61- Manage tool dependencies with `go get -tool` (Go 1.24)6263## Code Organization64- Package names should be concise and meaningful65- One package per directory66- Avoid circular dependencies between packages67- Use meaningful directory names that match package names68- Keep interfaces close to where they are used69- Follow standard Go project layout conventions7071## Context and Resource Management72- Always pass context.Context as the first parameter for operations that may be cancelled73- Implement proper context cancellation for all network operations74- Use context timeouts for external service calls75- Chain contexts appropriately without losing parent cancellation76- Always cancel derived contexts with `defer cancel()`77- Ensure goroutines are properly terminated when context is cancelled78- Monitor goroutine leaks using runtime statistics79- Limit concurrency with contexts or semaphores80- Use `os.Root` (Go 1.24) to sandbox filesystem access81 - Reliable protection against path traversal vulnerabilities82 - Basic usage pattern:83```go84 // Open a directory for sandboxed access85 root, err := os.OpenRoot("/safe/directory")86 if err != nil {87 return err88 }89 defer root.Close()9091 // All operations are contained within the root directory92 file, err := root.Open("config.json") // Opens /safe/directory/config.json93 file, err := root.Open("../config.json") // Still opens /safe/directory/config.json9495 // Create subdirectories safely96 err := root.Mkdir("uploads", 0755) // Creates /safe/directory/uploads9798 // For recursive operations, use OpenRoot again99 subdir, err := root.OpenRoot("uploads") // Opens /safe/directory/uploads as a new Root100 defer subdir.Close()101```102 - Handles symlinks securely (will not follow symlinks outside the root directory)103 - Prevents time-of-check/time-of-use (TOCTOU) race conditions104 - Platform-specific implementations (Unix uses openat, Windows uses handle restrictions)105 - See also: https://go.dev/blog/osroot for complete documentation106- Consider `runtime.AddCleanup` (Go 1.24) for finalizers if needed107- Explore `runtime/weak` package (Go 1.24) for weak references in caches108109## File System Security110- Use `os.Root` for all operations where filenames are untrusted or externally provided111- Replace common unsafe patterns with safe equivalents:112 - Instead of: `os.Open(filepath.Join(baseDir, untrustedPath))`113 - Use: `os.OpenInRoot(baseDir, untrustedPath)` (Go 1.24)114- When building a wrapped filesystem with custom validation, use `os.Root`:115```go116 // Example secureFS implementation with os.Root117 type secureFS struct {118 baseDir string119 root *os.Root120 }121122 func newSecureFS(baseDir string) (*secureFS, error) {123 // Create base directory if needed124 if err := os.MkdirAll(baseDir, 0755); err != nil {125 return nil, err126 }127128 // Open sandboxed root129 root, err := os.OpenRoot(baseDir)130 if err != nil {131 return nil, err132 }133134 return &secureFS{135 baseDir: baseDir,136 root: root,137 }, nil138 }139140 // Methods operate within sandbox141 func (fs *secureFS) OpenFile(relativePath string, flag int, perm os.FileMode) (*os.File, error) {142 // All paths are relative to root, cannot escape143 return fs.root.OpenFile(relativePath, flag, perm)144 }145```146- For edge cases where extra layers of protection are needed, combine `os.Root` with:147 - `filepath.IsLocal()` - Validates paths don't contain traversal components148 - `filepath.EvalSymlinks()` - Resolves symlinks before validation149- Remember `os.Root` limitations:150 - Not all operations available (e.g., no `RemoveAll`)151 - Implementation varies by platform (see docs for platform-specific details)152153## Code Style154- Functions should be focused and concise (typically under 50 lines)155- Keep cognitive complexity low (aim for under 50)156- Use switch statements instead of long if-else chains157- Combine related parameter types into structs when function has more than 3 parameters158- Combine parameter types when multiple parameters have the same type (`func(a, b string)` instead of `func(a string, b string)`)159- Use consistent naming conventions:160 - Use MixedCaps or mixedCaps rather than underscores161 - Use short, clear variable names162 - Acronyms should be consistently cased (HTTP, URL, ID)163- Document exported functions, types, and packages164- Name return values in function signatures for better documentation and to avoid gocritic unnamedResult errors, especially for functions returning multiple values of the same type165- Avoid duplicate imports of the same package166- Group similar declarations together167- Order struct fields to minimize padding168169## Error Handling170- Always check error returns, including from defer statements171- Use errors.Is() and errors.As() for error comparison instead of == or != operators172- Use error wrapping with fmt.Errorf("... %w", err) to preserve error types173- Create custom error types or sentinel errors for important error cases174- Propagate context.Canceled and context.DeadlineExceeded properly175- Return errors, don't panic (especially in libraries)176- Return early for error conditions177- Implement proper error logging and tracing178- Check errors from all I/O operations, especially in defer statements179- Consider errors.Join (Go 1.20+) to combine multiple errors into one180181## Resource Management and Leak Prevention182- Implement proper resource cleanup in defer statements183- Always check errors returned from cleanup operations in defer statements184- Use sync.WaitGroup to wait for goroutines to complete185- Close channels when no longer needed186- Implement proper connection pooling with maximum limits187- Use resource pooling for frequently created/destroyed objects188- Monitor goroutine count and resource usage189- Implement circuit breakers for external service calls190- Use leaktest in tests to detect goroutine leaks191- Implement proper cleanup for temporary resources192- Monitor system resources (file descriptors, memory, etc.)193- Use `runtime.AddCleanup` (Go 1.24) instead of SetFinalizer for cleaner finalizers194- Explore weak references (Go 1.24) for caches that shouldn't prevent GC195196## Performance and Safety197- Use pointers for large structs or when mutation is needed198- Implement proper mutex locks for shared resources199- Pre-allocate slices when size is known200- Use sync.Pool for frequently allocated objects201- Avoid unnecessary string concatenation; use strings.Builder202- Use buffered I/O operations203- Implement proper connection pooling204- Use sync.Map for concurrent map access205- Avoid multiplication of time durations (use time.Duration directly)206- Pass large structs by pointer to avoid copying207- Combine multiple append operations into a single call when possible208- Leverage modern Go features:209 - Range over function types for cleaner iteration (Go 1.23+)210 - Profile Guided Optimization for performance-critical code211 - Improved timer implementation (Go 1.23+)212 - New atomic operations213 - Optimized map implementation (Go 1.24)214- Use generics where appropriate, with improved type inference (Go 1.21+)215- Benefit from GC tuning improvements (Go 1.21+) for reduced tail latency216217## Defensive Programming218- Validate all input parameters219- Check slice bounds before accessing elements220- Verify map keys exist before access221- Handle nil pointer cases explicitly222- Don't check for nil before using len() on slices or maps (len() is defined as zero for nil slices/maps)223- Never pass nil contexts; use context.TODO() or context.Background() if unsure224- Use consistent, typed string keys for context values (avoid raw string type)225- Use context.Context for cancellation and timeouts226- Implement proper timeouts for network operations227- Use proper input sanitization228- Implement rate limiting where appropriate229230## Testing231- Write table-driven tests for all packages232- Use subtests (t.Run) for logically grouped cases233- Name test functions correctly (TestXxx, BenchmarkXxx, etc.)234- Use t.Cleanup() for test cleanup instead of custom solutions235- Use t.TempDir() for temporary test directories236- Use t.Setenv() to set environment variables for tests237- Use t.Parallel() when tests can run concurrently238- Implement benchmark tests with b.Loop() (Go 1.24) instead of manual loops239- Use the Go fuzzing engine with FuzzXxx functions240- Profile and optimize iteratively using Go's built-in tools241- Regularly run go vet with test analyzers (Go 1.24) to catch test mistakes242243## Cross-Platform Compatibility244- Use filepath.Join instead of string concatenation for paths245- Use os.PathSeparator when necessary246- Handle file permissions appropriately247- Use build tags for platform-specific code248- Test on both Linux and Darwin regularly249- Use proper line endings250- Handle filesystem case sensitivity differences251- Use os.Root (Go 1.24) for sandboxed filesystem access252 - Be aware of platform-specific behavior:253 - On Unix: Uses openat() family of syscalls for secure access254 - On Windows: Uses handle-based access and prevents traversal255 - On WASI: Uses the WASI preview 1 filesystem API256 - On js/WASM: May be vulnerable to TOCTOU races (check docs)257258## Documentation259- Document all exported types, functions, and packages260- Include examples in documentation261- Provide usage examples in README262- Document any platform-specific considerations263- Include license information264- Document build and test procedures265266## Dependencies267- Minimize external dependencies268- Use go.mod for dependency management269- Pin dependency versions270- Update go version in go.mod to latest supported version271- Run go mod tidy regularly (or go mod tidy -diff in Go 1.23+)272- Manage tool dependencies with go get -tool (Go 1.24)273- Regularly update dependencies274- Audit dependencies for security issues275- Document required external services276277## Monitoring and Observability278- Implement proper logging with log/slog (Go 1.21+)279- Use structured logging formats280- Include trace IDs in logs281- Implement metrics collection282- Add health check endpoints283- Include proper debugging information284- Implement proper panic recovery285286## Security287- Use proper input validation288- Implement secure password handling289- Use proper encryption for sensitive data290- Implement rate limiting291- Use proper authentication and authorization292- Handle sensitive data appropriately293- Implement secure session management294- Use latest crypto packages from standard library (Go 1.24)295- Consider FIPS 140-3 compliance mechanisms (Go 1.24)296297## Build and Deployment298- Use proper build tags299- Implement proper versioning300- Implement proper signal handling301- Use proper environment variable handling302- Implement graceful shutdown303- Handle configuration properly304- Use new octal literal style (0o644 instead of 0644)305- Set up CI/CD pipelines with linter checks and tests306- Consider Profile-Guided Optimization (PGO) for performance-critical applications307308## Tools309- Use go vet with stdversionanalyzer to check version compatibility310- Use go vet test analyzer (Go 1.24) to catch test mistakes311- Run golangci-lint regularly with appropriate linters:312 - durationcheck: For detecting incorrect operations with time.Duration313 - errcheck: To ensure error returns are checked314 - errorlint: To enforce errors.Is/errors.As usage315 - gocognit: To keep cognitive complexity manageable316 - gocritic: To detect various code improvement opportunities317 - gosimple: To simplify code318 - ineffassign: To detect ineffectual assignments319 - staticcheck: For wide range of code improvements320 - unconvert: To eliminate unnecessary type conversions321- Configure linter settings via .golangci.yml file322- Consider enabling Go telemetry (opt-in) to help improve Go323- Use go env -changed to identify non-default environment settings324- Leverage go mod tidy -diff to preview dependency changes325- Use godebug directive in go.mod for debugging settings326- Run tests with the race detector for non-trivial concurrent code
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| tphakala/birdnet-go.cursor/rules/database.mdc · 1.6k | Cursor rules | databasedo-not | 45/100 | today | |
| tphakala/birdnet-go.cursor/rules/frontend.mdc · 1.6k | Cursor rules | dependenciesuido-not | 61/100 | today | |
| tphakala/birdnet-go.cursor/rules/go_test.mdc · 1.6k | Cursor rules | setupteststyletesting-strategy+1 | 56/100 | today | |
| tphakala/birdnet-goAGENTS.md · 1.6k | AGENTS.md | teststylegitdo-not+1 | 78/100 | today | |
| tphakala/birdnet-goCLAUDE.md · 1.6k | CLAUDE.md | buildtestlint-formatstyle+8 | 100/100 | today | |
| tphakala/birdnet-gofrontend/CLAUDE.md · 1.6k | CLAUDE.md | setuptestlint-formatstyle+7 | 84/100 | today | |
| tphakala/birdnet-gofrontend/src/lib/desktop/components/CLAUDE.md · 1.6k | CLAUDE.md | teststylearchui | 70/100 | today | |
| tphakala/birdnet-gofrontend/src/lib/desktop/components/ui/CLAUDE.md · 1.6k | CLAUDE.md | styleuidocs | 54/100 | today | |
| tphakala/birdnet-gofrontend/src/lib/desktop/features/settings/CLAUDE.md · 1.6k | CLAUDE.md | buildstylearchtypes+2 | 66/100 | today | |
| tphakala/birdnet-gofrontend/static/messages/CLAUDE.md · 1.6k | CLAUDE.md | archuido-notagent-behaviour | 67/100 | today | |
| tphakala/birdnet-gofrontend/tools/CLAUDE.md · 1.6k | CLAUDE.md | no sections | 65/100 | today | |
| tphakala/birdnet-gointernal/CLAUDE.md · 1.6k | CLAUDE.md | buildteststylearch+5 | 88/100 | today | |
| tphakala/birdnet-gointernal/api/v2/CLAUDE.md · 1.6k | CLAUDE.md | teststylesecurityapi+1 | 84/100 | today | |
| tphakala/birdnet-gointernal/errors/CLAUDE.md · 1.6k | CLAUDE.md | styleuiperformancedo-not+1 | 61/100 | today |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| bybren-llc/safe-agentic-workflow.cursor/rules/10-backend-python.mdc · 399 | Cursor rules | testlint-formatstylegit+4 | 97/100 | today |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/tphakala-birdnet-go-cursor-rules-go)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.