10 KiB
Go Jdenticon - Development Guide for Claude Code
Project Overview
Go Jdenticon is a Go library for generating highly recognizable identicons - geometric avatar images generated deterministically from any input string. This is a Go port of the JavaScript library Jdenticon.
Critical Achievement: This implementation maintains byte-for-byte identical SVG output with the JavaScript reference implementation through careful algorithm replication.
Key Features
- Renders identicons as PNG or SVG with no external dependencies
- Generates consistent, deterministic identicons from any input string
- Highly customizable color themes and styling options
- Command-line tool included for standalone usage
- JavaScript reference compatibility - produces identical output to the original JavaScript library
Project Structure
go-jdenticon/
jdenticon/ # Public API package
config.go # Public configuration options
generate.go # Main API functions
hash.go # Hash computation and parsing
reference_test.go # JavaScript compatibility tests
internal/
engine/ # Core generation logic
generator.go # Main generation algorithm (CRITICAL FILE)
shapes.go # Shape rendering with transforms
color.go # Color theme generation
config.go # Internal configuration
layout.go # Grid layout system
transform.go # Coordinate transformations
renderer/ # Output rendering
renderer.go # Base renderer interface
svg.go # SVG output (maintains z-order!)
png.go # PNG output using Go imaging
cmd/jdenticon/ # Command-line tool
jdenticon-js/ # JavaScript reference implementation
example_usage.go # Demo and testing
Build & Test Commands
# Run all tests
go test ./jdenticon ./internal/...
# Run specific test packages
go test ./jdenticon
go test ./internal/engine
go test ./internal/renderer
# Run JavaScript compatibility tests (CRITICAL)
go test ./jdenticon -run TestJavaScriptReferenceCompatibility
# Build command-line tool
go build -o jdenticon cmd/jdenticon/main.go
# Generate demo avatars
go run example_usage.go
# Quick test with visualization
go run quick_test.go
Core Algorithm Architecture
Generation Flow (internal/engine/generator.go)
The generation algorithm follows this exact sequence to match JavaScript:
-
Hash Parsing: Extract values from specific positions in SHA1 hash
- Positions 2,3: Side shape selection
- Positions 4,5: Corner shape selection
- Position 1: Center shape selection
- Position 0: Main hue value
-
Shape Selection: Use hard-coded position arrays (NOT layout engine)
positions := [][]int{{1, 0}, {2, 0}, {2, 3}, {1, 3}, {0, 1}, {3, 1}, {3, 2}, {0, 2}} -
Color Generation: Create theme colors from hue with specific lightness ranges
-
Shape Rendering: Process in exact order:
- Outer shapes (sides + corners) with rotations
- Center shapes with incremental rotation when no rotation hash
Critical Implementation Details
Shape Selection Algorithm (generator.go:67-95)
// CRITICAL: Use exact hash positions to match JavaScript
sideShapeIndex := parseHex(hash, 2, 1) % len(outerShapes)
cornerShapeIndex := parseHex(hash, 4, 1) % len(outerShapes)
centerShapeIndex := parseHex(hash, 1, 1) % len(centerShapes)
Transform Application (generator.go:125-135)
// Center shapes: increment rotation per position when no rotation hash
if rotationHashIndex == -1 {
transformRotation = i % 4
} else {
transformRotation = parseHex(hash, rotationHashIndex, 1) % 4
}
Z-Order Rendering (renderer/svg.go)
CRITICAL: SVG renderer preserves insertion order, NOT alphabetical:
// Maintain colorOrder to preserve z-order
for _, color := range r.colorOrder {
// Render in insertion order
}
JavaScript Reference Compatibility
⚠️ CRITICAL REQUIREMENT ⚠️
THE jdenticon/reference_test.go FILE MUST ALWAYS PASS
This is the MOST IMPORTANT test in the entire codebase. It validates that our Go implementation produces byte-for-byte identical SVG output to the JavaScript reference implementation.
NEVER commit code that breaks this test. NEVER merge PRs with failing reference tests.
Reference Files Location
- JavaScript reference SVGs:
jdenticon-js/test/ - Go compatibility test:
jdenticon/reference_test.go
Test Cases
The compatibility test validates three critical cases:
"test-hash"at 64px"example1@gmail.com"at 64px"example2@yahoo.com"at 64px
These tests MUST pass - they verify byte-for-byte identical SVG output.
Running the Critical Test
# Run ONLY the reference compatibility test
go test ./jdenticon -run TestJavaScriptReferenceCompatibility -v
# This test MUST show:
# === RUN TestJavaScriptReferenceCompatibility/test-hash_@
# --- PASS: TestJavaScriptReferenceCompatibility/test-hash_@ (0.00s)
# === RUN TestJavaScriptReferenceCompatibility/example1@gmail.com_@
# --- PASS: TestJavaScriptReferenceCompatibility/example1@gmail.com_@ (0.00s)
# === RUN TestJavaScriptReferenceCompatibility/example2@yahoo.com_@
# --- PASS: TestJavaScriptReferenceCompatibility/example2@yahoo.com_@ (0.00s)
If the Reference Test Fails
- STOP DEVELOPMENT - Do not proceed with other changes
- Investigate what changed in the generation algorithm
- Check hash parsing positions in
generator.go - Verify shape selection and rendering order
- Check SVG z-order in
renderer/svg.go - Compare against JavaScript implementation line by line
- DO NOT change the reference files to match Go output
- FIX the Go implementation to match JavaScript exactly
Key Compatibility Requirements
- Hash Parsing: Must use identical positions as JavaScript
- Shape Order: Must render in same sequence (outer shapes, then center)
- Position Arrays: Must use hard-coded JavaScript positions, not computed layout
- Transform Logic: Center shape rotation must increment when no rotation hash
- Circle Interface: Uses top-left + size (not center + radius)
- Z-Order: SVG elements must maintain insertion order
Common Development Patterns
Adding New Shape Types
- Update shape arrays in
generator.go - Implement rendering in
shapes.go - Add transform support if needed
- Always run compatibility tests
Modifying Color Generation
- Changes in
internal/engine/color.go - Ensure lightness ranges match JavaScript exactly
- Test with variety of hue values
Renderer Changes
- Update base interface in
renderer/renderer.go - Implement in both SVG and PNG renderers
- Critical: Maintain z-order in SVG renderer
Testing Strategy
Unit Tests
- Each component has comprehensive unit tests
- Focus on boundary conditions and edge cases
- All tests should pass consistently
Integration Tests
reference_test.go- MOST CRITICAL - JavaScript compatibilityintegration_test.go- Visual regression testing- PNG checksum validation for consistency
Manual Testing
- Run
example_usage.goto generate various avatar types - Verify visual output matches expectations
- Test edge cases (empty strings, long inputs, special characters)
Configuration System
Public API (jdenticon/config.go)
type Config struct {
Hue float64 // Color hue (0.0-1.0)
Saturation float64 // Color saturation (0.0-1.0)
Lightness float64 // Color lightness (0.0-1.0)
BackgroundColor string // Hex color or empty for transparent
Padding float64 // Padding as percentage (0.0-0.5)
}
Internal Configuration (internal/engine/config.go)
- More detailed color ranges and restrictions
- Validation logic for all parameters
- Builder pattern for complex configurations
Error Handling Patterns
- Input Validation: Validate size > 0, hash format, config ranges
- Graceful Degradation: Default to safe values for invalid inputs
- Clear Error Messages: Provide actionable error information
- No Panics: Always return errors, never panic in library code
Performance Considerations
- Caching: Generator caches theme colors for repeated use
- Memory Management: Reuse objects where possible
- PNG Generation: Uses efficient Go imaging library
- SVG Generation: String builder for optimal performance
Debugging & Troubleshooting
Visual Debug Tools
example_usage.go- Generates multiple test casesquick_test.go- Quick visualization- Generated avatars saved as PNG/SVG files
Common Issues
- Compatibility Test Failures: Usually indicates algorithm change
- Color Inconsistency: Check hue/lightness calculations
- Shape Positioning: Verify transform application
- Z-Order Problems: Check SVG renderer color ordering
Debug Hash Extraction
Use the hash parsing utilities to understand how values are extracted:
parseHex(hash, position, octets) // Extract specific hash segments
Future Development Guidelines
- Maintain Compatibility: Always run reference tests after changes
- Follow Go Conventions: Use standard Go patterns and idioms
- Test Coverage: Add tests for any new functionality
- Documentation: Update this guide for significant changes
- Performance: Profile before optimizing, measure impact
Dependencies
- Standard Library Only: No external dependencies for core functionality
- Testing: Uses standard Go testing framework
- Command Line: Uses standard
flagpackage
API Usage Examples
Basic Generation
icon := jdenticon.Generate("user@example.com", 200)
svg := icon.ToSVG()
png := icon.ToPNG()
With Custom Configuration
config := &jdenticon.Config{
Hue: 0.3,
Saturation: 0.7,
Lightness: 0.5,
Padding: 0.1,
}
icon := jdenticon.GenerateWithConfig("user@example.com", 200, config)
This implementation successfully achieves JavaScript reference compatibility while maintaining clean Go idioms and comprehensive test coverage.