Skip to content

Valgo

Valgo
Valgo

Type-safe, expressive, and extensible Go validation library
with i18n support.

val := v.Is(
v.String("Bob", "full_name").Not().Blank().LengthBetween(4, 20),
v.Number(17, "age").GreaterThan(18),
)
if !val.Valid() {
out, _ := json.MarshalIndent(val.ToError(), "", " ")
fmt.Println(string(out))
}
{
"age": [
"Age must be greater than \"18\""
],
"full_name": [
"Full name must have a length between \"4\" and \"20\""
]
}
Extended example

Compose ordinary Go functions into a complete registration flow with alternatives, dependent rules, and nested validation paths.

type Address struct {
Line1 string
City string
Country string
PostalCode string
}
type Registration struct {
Name string
Email string
Password string
PasswordConfirmation string
ContactPreference string
ReferralCode string
Address Address
}
func validateRegistration(input Registration) *v.Validation {
return v.Is(
v.String(input.Name, "name").Not().Blank().LengthBetween(2, 80),
v.String(input.Email, "email").Not().Blank(),
v.String(input.Password, "password").Not().Blank().LengthBetween(10, 64),
v.String(input.ContactPreference, "contact_preference").
EqualTo("email").Or().EqualTo("sms"),
v.String(input.ReferralCode, "referral_code").
Empty().OrElse().MatchingTo(regexp.MustCompile(`^[A-Z0-9]{6,12}$`)),
).IfPathValid("password",
v.Is(v.String(input.PasswordConfirmation, "password_confirmation").
EqualTo(input.Password)),
).In("address",
v.Is(
v.String(input.Address.Line1, "line1").Not().Blank(),
v.String(input.Address.City, "city").Not().Blank(),
v.String(input.Address.Country, "country").Not().Blank().EqualTo("US"),
v.String(input.Address.PostalCode, "postal_code").Not().Blank(),
).WhenAllValid([]string{"country", "postal_code"}, func(val *v.Validation) {
if err := verifyPostalCode("US", input.Address.PostalCode); err != nil {
val.AddErrorMessage("postal_code", "Postal code could not be verified")
}
}),
)
}
Installing
go get github.com/cohesivestack/valgo
Agent skill
npx skills add cohesivestack/valgo –skill valgo