asaskevich/govalidator
[Go] Package of validators and sanitizers for strings, numerics, slices and structs
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓26+ active contributors
- ✓MIT licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ⚠Concentrated ownership — top contributor handles 51% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/asaskevich/govalidator)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/asaskevich/govalidator on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: asaskevich/govalidator
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/asaskevich/govalidator shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 2w ago
- 26+ active contributors
- MIT licensed
- CI configured
- ⚠ Concentrated ownership — top contributor handles 51% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live asaskevich/govalidator
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/asaskevich/govalidator.
What it runs against: a local clone of asaskevich/govalidator — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in asaskevich/govalidator | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 47 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of asaskevich/govalidator. If you don't
# have one yet, run these first:
#
# git clone https://github.com/asaskevich/govalidator.git
# cd govalidator
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of asaskevich/govalidator and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "asaskevich/govalidator(\\.git)?\\b" \\
&& ok "origin remote is asaskevich/govalidator" \\
|| miss "origin remote is not asaskevich/govalidator (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "validator.go" \\
&& ok "validator.go" \\
|| miss "missing critical file: validator.go"
test -f "types.go" \\
&& ok "types.go" \\
|| miss "missing critical file: types.go"
test -f "patterns.go" \\
&& ok "patterns.go" \\
|| miss "missing critical file: patterns.go"
test -f "utils.go" \\
&& ok "utils.go" \\
|| miss "missing critical file: utils.go"
test -f "error.go" \\
&& ok "error.go" \\
|| miss "missing critical file: error.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 47 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~17d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/asaskevich/govalidator"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
govalidator is a Go package that provides validators and sanitizers for strings, numerics, slices, and structs—implementing string format checks (email, URL, IP), type conversions, and struct field validation through tags. It's modeled after the JavaScript validator.js library and enables declarative validation via struct tags like valid:"email,required". Flat package structure: core validators split by domain (validator.go for strings, numerics.go for numbers, arrays.go for slices, converter.go for type coercion), with parallel *_test.go and *_example_test.go files for each. utils.go and types.go provide helpers. No subpackages—all validation logic exported at package level.
👥Who it's for
Go backend developers and API builders who need to validate user input (form submissions, JSON payloads, config files) without writing repetitive validation logic. Common in web frameworks, microservices, and CLI tools that consume external data.
🌱Maturity & risk
Production-ready. The v12 release (go.mod shows v12 path), CI/CD pipelines running (CircleCI, Travis, Wercker configs present), comprehensive test suite across validator_test.go, numerics_test.go, arrays_test.go, and example tests. Activity appears steady with standard Go project practices; stable API for a validator library.
Low risk for core use: single-maintainer (asaskevich) with no visible complex external dependencies (go.mod shows v1.13+, minimal deps expected). Risk factors: validation rules may lag emerging security standards (email/URL specs evolve), and struct tag parsing is strictly opinionated (breaking changes if tag syntax changes). Monitor releases for security-related fixes.
Active areas of work
Cannot determine from file list alone. Check GitHub releases and commit history for recent activity, but README indicates active maintenance with v12 branch and security.md presence suggesting ongoing security reviews.
🚀Get running
go get github.com/asaskevich/govalidator/v12
Then import in your Go file:
import "github.com/asaskevich/govalidator/v12"
No build step needed; Go's standard build tools handle the rest.
Daily commands: Not a runnable application. It's a library. Run tests via:
go test ./...
go test -bench=. ./...
See arrays_example_test.go, validator_example_test.go, etc. for usage patterns; run go test -run Example to see them execute.
🗺️Map of the codebase
validator.go— Core validation entry point and primary API surface; defines the main validation functions and dispatcher logic that all validators depend on.types.go— Defines core type definitions and validation tags; essential for understanding the struct validation framework used throughout.patterns.go— Central registry of regex patterns for string validation; all pattern-based validators depend on these definitions.utils.go— Utility functions for type conversion and common validation helpers; widely reused across all validation modules.error.go— Error type definitions and validation error handling; critical for understanding error propagation across the codebase.arrays.go— Array and slice validation logic; one of the main domain-specific validators alongside strings and numerics.numerics.go— Numeric validation and conversion logic; key domain for a large portion of validation use cases.
🧩Components & responsibilities
- validator.go (reflect, regexp) — Dispatch point for all validators; implements IsEmail, IsURL, IsIP, IsPhone, ValidateStruct, etc.
- Failure mode: Invalid input returns false or populated ErrorMap; no panic.
- patterns.go (regexp.Compile) — Central pattern registry; pre-compiles and exports regex patterns for email, URL, IPv4/v6, credit card, etc.
- Failure mode: Invalid pattern causes init-time panic; not recoverable.
- types.go (struct tags, constants) — Type definitions for validation rules and struct tags; defines tag constants and validation operators.
- Failure mode: Invalid tag syntax is ignored or causes validator to skip field; no hard error.
- utils.go (strconv, strings, reflect) — Helper functions for type conversion, string operations, and common validation logic.
- Failure mode: Failed conversions return zero value and false; caller must check both return values.
- error.go (error interface, map) — Error type definitions; ErrorMap collects field-level validation failures.
- Failure mode: Empty ErrorMap indicates all validations passed; non-empty indicates partial or full failure.
- converter.go (strconv, regexp) — Sanitizers and type converters (ToInt, ToString, ToFloat); transforms input values.
- Failure mode: Invalid input returns zero value and error; caller responsible for checking error return
🛠️How to make changes
Add a new string validator
- Define a new regex pattern in patterns.go if needed, or reuse an existing one (
patterns.go) - Implement the validator function in validator.go following the naming convention IsXxx() (
validator.go) - Write unit tests in validator_test.go with test cases for valid, invalid, and edge cases (
validator_test.go) - Write an example test in validator_example_test.go following the ExampleIsXxx pattern (
validator_example_test.go)
Add a new numeric validator or type check
- Implement the IsXxx() validator function in numerics.go (
numerics.go) - Use existing helper functions from utils.go for type assertion or conversion (
utils.go) - Add test cases in numerics_test.go covering boundary conditions (
numerics_test.go) - Add example usage in numerics_example_test.go (
numerics_example_test.go)
Add support for a new struct validation tag
- Update the tag parsing logic in validator.go ValidateStruct() function (
validator.go) - Define the tag constant and documentation in types.go (
types.go) - Add test cases in validator_test.go with struct examples using the new tag (
validator_test.go) - Document error cases in error.go if the tag produces new error types (
error.go)
Add a new converter/sanitizer function
- Implement the ToXxx() or SanitizeXxx() function in converter.go (
converter.go) - Reuse common utility functions from utils.go for type conversion (
utils.go) - Add tests in converter_test.go covering valid and invalid inputs (
converter_test.go) - Add examples in converter_example_test.go showing typical usage (
converter_example_test.go)
🔧Why these technologies
- Go 1.13+ — Leverages recent Go features for error handling, module system, and reflect optimizations while maintaining broad compatibility.
- Compiled regex patterns (regexp.Compile) — Pre-compiled patterns avoid recompilation overhead; patterns stored as package-level vars in patterns.go.
- Struct reflection (reflect.StructTag) — Enables declarative validation via struct tags; ValidateStruct uses reflection to introspect fields and tags.
- Type assertions over type switches — Minimal performance overhead for the common-case validators; used in utils.go for value extraction.
⚖️Trade-offs already made
-
Single regex pattern global registry (patterns.go) vs. lazy-compiled on-demand
- Why: Pre-compilation trades memory for speed; all validators get fast, cached pattern access without init cost.
- Consequence: Fixed memory footprint (~100KB) but guaranteed <1μs pattern lookup; no per-call compilation.
-
ErrorMap (map[string]string) for struct validation errors vs. slice of structured errors
- Why: Map allows field-name-keyed errors matching Go idiom; easier to present per-field error messages.
- Consequence: Cannot represent multiple errors per field; developers must parse error strings for detailed error info.
-
Separate IsXxx() validators vs. unified Validate() dispatcher function
- Why: Allows composable, testable individual validators; users pick only what they need.
- Consequence: More functions to maintain; no global validation config; each validator reinvents error handling slightly.
-
Custom converter functions (ToInt, ToString, etc.) vs. relying on type assertions
- Why: Explicit converters document intent and handle edge cases (e.g., string to int with base detection).
- Consequence: Larger API surface; converters may shadow standard Go type conversions.
🚫Non-goals (don't propose these)
- Does not provide custom validator registration or DSL for user-defined rules.
- Does not handle authentication, authorization, or security policy enforcement.
- Does not persist validation metadata or audit validation events.
- Does not support internationalization (i18n) for error messages.
- Does not integrate with specific frameworks (echo, gin, chi); operates as standalone library.
🪤Traps & gotchas
Struct tag parsing is strict: Fields with no tag and FieldsRequiredByDefault enabled will fail validation (use valid:"-" or valid:"optional" to exempt). SetNilPtrAllowedByRequired changes behavior: Nil pointers normally fail required validation, but this flag inverts it—can cause subtle bugs if toggled globally. Regex compilation happens at init: patterns.go compiles patterns once; if you extend it, ensure patterns compile or the package panics. ValidateStruct uses reflection: Validating thousands of structs per second in tight loops may show reflection overhead; benchmark if performance critical.
🏗️Architecture
💡Concepts to learn
- Struct field validation via tags — The core pattern of this library:
valid:"email,required"tags on fields are parsed at runtime by ValidateStruct() using reflection—understanding Go reflection and struct tags is essential to extend or debug validation rules. - Regular expression patterns — Email, URL, IP, and UUID validators rely on compiled regex patterns in patterns.go; regex accuracy directly impacts validation correctness and false positive rates.
- Type assertion and reflection — ValidateStruct() uses reflection to inspect struct fields at runtime and convert values—core Go technique for generic validation; essential for understanding how the package handles arbitrary struct shapes.
- Validator chaining — Struct tags like
valid:"email,required,length(5|40)"chain multiple validators; the parser splits on commas and applies validators in sequence—understand how validation rules compose. - Sanitization vs. validation — converter.go and utils.go provide sanitizers (ToInt, ToString) separate from pure validators—understanding the difference prevents accidentally modifying input during validation.
- Error accumulation in batch validation — ValidateStruct() returns ValidationErrors (a map of field names to error slices) allowing inspection of all failures at once, not just the first—critical for user-facing forms that need comprehensive feedback.
- Lazy pattern compilation — patterns.go compiles complex regexes once at package init, reusing them across validator calls—important for performance; modifying patterns.go requires understanding init-time costs.
🔗Related repos
go-playground/validator— Direct competitor: more feature-rich struct validator with custom rules, cross-field validation, and better error messages; heavier but more flexible.chriso/validator.js— Original JavaScript inspiration: govalidator ports many validators from here, useful for understanding original design intent and feature parity.golang/go— Upstream dependency: govalidator relies on stdlib regexp, reflect, and strconv; understanding Go's built-ins is critical for contributing.google/uuid— Companion package: often used with govalidator's IsUUID validator; commonly validated together in Go services.lib/pq— Common downstream user: PostgreSQL driver for Go that processes user input—many projects validate data before inserting with pq using govalidator.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add GitHub Actions CI workflow to replace Travis CI
The repo still uses .travis.yml and CircleCI (config.yml), which are legacy CI systems. GitHub Actions is the modern standard for GitHub repos and would provide faster, more integrated CI/CD. This would improve contributor experience and reduce maintenance overhead.
- [ ] Create .github/workflows/test.yml with Go test matrix (1.13, 1.19, 1.20, 1.21)
- [ ] Add coverage reporting step using codecov/codecov-action
- [ ] Add linting step using golangci-lint
- [ ] Add benchmark comparison for performance regressions
- [ ] Update README.md to replace Travis CI badge with GitHub Actions badge
- [ ] Remove or deprecate .travis.yml and .circleci/config.yml
Add comprehensive integration tests for validator.go struct validation
The validator.go file handles struct tag validation which is core functionality, but the test file (validator_test.go) likely lacks edge cases for complex nested structs, custom validators, and error handling. Adding integration tests would improve reliability and serve as documentation.
- [ ] Review existing validator_test.go to identify gaps in struct validation coverage
- [ ] Add tests for nested struct validation with multiple tag types
- [ ] Add tests for custom validator function error handling and edge cases
- [ ] Add tests for validator behavior with pointer fields, slices, and maps
- [ ] Add tests for error message formatting and ValidatorError types (see error.go)
- [ ] Create validator_integration_test.go for real-world struct validation scenarios
Add examples and test coverage for converter.go sanitization functions
The converter.go file (string/value conversion) has a _test.go file but the converter_example_test.go is likely sparse. Adding documented examples would help users understand sanitization capabilities and serve as integration tests.
- [ ] Review converter_example_test.go for coverage gaps
- [ ] Add ExampleToInt, ExampleToFloat, ExampleToBoolean examples with edge cases
- [ ] Add ExampleToJSON and custom type conversion examples
- [ ] Add ExampleEscape functions (URL, HTML, SQL escaping if present)
- [ ] Test and document error cases (invalid input handling)
- [ ] Ensure all examples are executable and match actual function signatures in converter.go
🌿Good first issues
- Add benchmark comparisons in numerics_benchmark_test.go and arrays_benchmark_test.go for newly added validators to establish performance baselines, similar to existing benchmarks in validator_benchmark_test.go.
- Write example tests for less-common validators (e.g., IsFloat with specific precision, IsPort range validation) in converter_example_test.go and numerics_example_test.go to improve documentation coverage.
- Add support for custom validator functions in struct tags (e.g.,
valid:"custom:myValidator") by extending the tag parser in validator.go's ValidateStruct()—currently only built-in validators are supported.
⭐Top contributors
Click to expand
Top contributors
- @asaskevich — 51 commits
- [@Alex Saskevich](https://github.com/Alex Saskevich) — 6 commits
- @sschiz — 5 commits
- @shintarou37 — 3 commits
- @ArshiAAkhavan — 3 commits
📝Recent commits
Click to expand
Recent commits
3dd3875— - minor readme.md changes (asaskevich)0cc4e49— - add examples, add benchmarks (asaskevich)5fdb4e7— - remove from readme out-of-date links and badges (asaskevich)d446155— - update copyrights (asaskevich)375f905— Prepare release v1.2.0 (asaskevich)13dbbb1— - add tests and logic from #504, closes it as merged (asaskevich)ae65711— Merge pull request #509 from varmakarthik12/fix-#507 (asaskevich)12394c0— Merge branch 'master' into fix-#507 (asaskevich)ff462b5— Merge pull request #510 from layou233/use-json-valid (asaskevich)f19c2f2— Merge pull request #506 from shushantrishav/master (asaskevich)
🔒Security observations
The govalidator repository demonstrates reasonable security practices with a defined security policy and responsible disclosure mechanism. However, there are several areas for improvement: (1) The Go runtime version specification is outdated and should be updated to a supported version to benefit from security patches, (2) Potential ReDoS vulnerabilities in regex patterns should be reviewed, and (3) The security support policy is narrow. The codebase appears to be a pure validation library without external dependencies (based on provided content), which reduces supply chain risk. No hardcoded credentials or obvious injection vulnerabilities are evident from the file structure analysis. Overall, the project maintains good security posture but would benefit from modernizing the Go version requirement and expanding security patch coverage.
- Low · Outdated Go Version Specification —
go.mod. The go.mod file specifies Go 1.13 as the minimum version. This version was released in September 2019 and is no longer supported. Using outdated Go versions may expose the project to known security vulnerabilities in the Go runtime itself. Fix: Update the Go version to a currently supported release (1.21 or later). Review the Go security policy and update to the latest stable version. - Low · Missing Dependency Pinning Details —
go.mod. The go.mod file content shows only the module declaration and Go version, but no explicit dependency versions are provided. This could lead to unexpected behavior if indirect dependencies are updated. Fix: Ensure go.mod contains complete dependency information with pinned versions. Run 'go mod tidy' and commit the full go.mod and go.sum files to version control. - Low · Potential Regex ReDoS in Validator Functions —
patterns.go. The file 'patterns.go' likely contains regular expression patterns used for validation. Regular expressions can be vulnerable to ReDoS (Regular Expression Denial of Service) attacks if not carefully crafted, potentially causing performance issues or denial of service. Fix: Review all regex patterns in patterns.go for complexity and potential ReDoS vulnerabilities. Consider using timeout mechanisms for regex evaluation. Test with adversarial input patterns. - Low · Limited Security Policy Scope —
SECURITY.md. The SECURITY.md indicates that security updates are applied only to the latest release. This means users on older versions will not receive security patches, creating a fragmented security landscape. Fix: Consider supporting security patches for at least the last two major versions. Establish a clear security release policy and communicate it to users. Consider using semantic versioning with extended support.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.