govalid

High-performance, type-safe validation library for Go with zero allocations

govalid

High-performance, type-safe validation library for Go with zero allocations

GitHub Go Report Card License: MIT

Overview

govalid is a Go package designed to generate type-safe validation code for structs based on markers. It provides a mechanism to apply validation rules directly in the code by marking struct fields with specific markers. The tool processes these markers and generates corresponding validation functions with zero heap allocations.

Key Features

  • 🚀 Zero Allocations: All validators perform zero heap allocations
  • 🔒 Type Safety: Generated validation functions with proper types
  • ⚡ High Performance: 5x to 44x faster than reflection-based validators
  • 📝 Marker-Based: Simple comment-based validation rules
  • 🔧 Code Generation: Generates optimized validation functions
  • 🎯 Comprehensive: Support for all common validation patterns

Quick Start

Installation

1
go install github.com/sivchari/govalid/cmd/govalid@latest

Basic Usage

  1. Define your struct with markers:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

type User struct {
    // +govalid:required
    Name string `json:"name"`
    
    // +govalid:email
    Email string `json:"email"`
    
    // +govalid:gte=18
    Age int `json:"age"`
    
    // +govalid:maxlength=100
    Bio string `json:"bio"`
}
  1. Generate validation code:
1
govalid ./...

This generates validation code like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Code generated by govalid; DO NOT EDIT.

var (
    ErrNilUser = errors.New("input User is nil")
    ErrUserNameRequiredValidation = errors.New("field Name is required")
    ErrUserEmailEmailValidation = errors.New("field Email must be a valid email address")
    ErrUserAgeGTEValidation = errors.New("field Age must be greater than or equal to 18")
    ErrUserBioMaxLengthValidation = errors.New("field Bio must have at most 100 characters")
)

func ValidateUser(t *User) error {
    if t == nil {
        return ErrNilUser
    }
    if len(t.Name) == 0 {
        return ErrUserNameRequiredValidation
    }
    if !validationhelper.IsValidEmail(t.Email) {
        return ErrUserEmailEmailValidation
    }
    if !(t.Age >= 18) {
        return ErrUserAgeGTEValidation
    }
    if !(utf8.RuneCountInString(t.Bio) <= 100) {
        return ErrUserBioMaxLengthValidation
    }
    return nil
}

Note: Error variable names include the struct name as a prefix (e.g., ErrUserNameRequiredValidation) to prevent naming conflicts when multiple structs have fields with the same name.

  1. Use the generated validation:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
func main() {
    user := &User{
        Name:  "Alice",
        Email: "alice@example.com",
        Age:   25,
        Bio:   "Software developer",
    }
    
    if err := ValidateUser(user); err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("User is valid!")
}

Performance Highlights

  • 5x to 50x faster than popular validation libraries
  • Zero allocations across all validators
  • Sub-3ns execution for simple validators (Required, GT, LT)
  • Extended type support including maps, channels, and enums

📊 View detailed benchmark results →

Supported Validators

String Validators

  • govalid:required - Required field validation
  • govalid:minlength=N - Minimum string length (Unicode-aware)
  • govalid:maxlength=N - Maximum string length (Unicode-aware)
  • govalid:email - HTML5-compliant email validation
  • govalid:url - HTTP/HTTPS URL validation
  • govalid:uuid - RFC 4122 UUID validation

Numeric Validators

  • govalid:gt=N - Greater than validation
  • govalid:gte=N - Greater than or equal validation
  • govalid:lt=N - Less than validation
  • govalid:lte=N - Less than or equal validation

Collection Validators

  • govalid:minitems=N - Minimum collection size
  • govalid:maxitems=N - Maximum collection size

General Validators

  • govalid:enum=val1,val2,val3 - Enum validation

Why govalid?

🔥 Performance First

  • Zero allocations: No heap allocations during validation
  • Compile-time optimization: Generated code is optimized by the Go compiler
  • Minimal overhead: Direct field access with no reflection

🎯 Developer Experience

  • Familiar syntax: Similar to popular validation libraries
  • Type safety: Validation functions are generated with proper types
  • Clear error messages: Descriptive validation error messages

🚀 Production Ready

  • Extensive test coverage: Comprehensive unit and benchmark tests
  • Battle tested: Used in production environments
  • Maintained: Regular updates and improvements

Get Started

Ready to make your Go validation blazingly fast? Check out our Getting Started guide or browse the available validators.

Get Started → View on GitHub →

🚀

Zero Allocations

All validators perform zero heap allocations, making them perfect for high-performance applications.

0 B/op 0 allocs/op

Blazing Fast

5x to 44x faster than reflection-based validators with sub-nanosecond performance for simple operations.

1.96ns required 44.2x faster
🔒

Type Safe

Generated validation functions ensure type safety and catch errors during code generation.

Generation-time Type safe
📝

Simple Syntax

Familiar marker-based syntax similar to other validation libraries, easy to learn and use.

// +govalid:required
🎯

Comprehensive

Support for all common validation patterns plus unique features like CEL expressions, enum validation, and extended collection types.

Full featured
🔧

Production Ready

Battle-tested with extensive benchmarks and used in production environments.

Battle tested Production ready

Quick Example

See how easy it is to add validation to your Go structs:

1. Define your struct with markers

type User struct {
    // +govalid:required
    // +govalid:minlength=2
    Name string `json:"name"`
    
    // +govalid:email
    Email string `json:"email"`
    
    // +govalid:gte=18
    Age int `json:"age"`
}

2. Generate and use validation

# Generate validation code
govalid .
// Use generated validation
user := &User{
    Name: "Alice",
    Email: "alice@example.com",
    Age: 25,
}

if err := ValidateUser(user); err != nil {
    log.Fatal(err)
}

🚀 Exceptional Performance

govalid delivers 5x to 44x performance improvements with zero allocations

44x
faster validation
🚀
0
allocations
⏱️
~2ns
simple operations

View Detailed Benchmarks

Ready to Get Started?

Install govalid and start validating your Go structs with zero allocations and maximum performance.

Get Started View Validators Benchmarks GitHub