The Problem Every Developer Faces
You're building a form. Simple registration form. Email, password, done.
// Joi
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).required()
});
Two weeks later:
"Hey, can we make password 12 characters for enterprise users?"
You: Opens IDE, modifies code, writes tests, creates PR, waits for review, deploys
Product Manager: "Actually, can we A/B test 10 vs 12 characters first?"
You: Screams internally
What If Validation Wasn't Code?
What if validation rules were just... data?
[
{
"name": "email",
"validation": [
{ "rule": "required" },
{ "rule": "email" }
]
},
{
"name": "password",
"validation": [
{ "rule": "required" },
{ "rule": "minLength", "value": 8 }
]
}
]
That's it. Pure JSON.
No imports. No code. No deployment.
Introducing: Template-Based Validation
import { Validator } from '@teonord/validator';
// Your data
const formData = {
email: 'user@example.com',
password: 'pass123'
};
// Your validation rules (can be from anywhere)
const template = await fetch('/api/validation-rules').then(r => r.json());
// Validate
const result = new Validator(formData).validateTemplate(template);
if (!result.isValid) {
console.log(result.errors);
}
Notice what just happened:
✅ Validation rules fetched from API
✅ Zero code changes needed
✅ Rules can change without deployment
✅ Non-developers can modify rules
Real-World Game Changers
1. Multi-Tenant SaaS
Different customers, different rules.
// Enterprise customer: strict validation
const enterpriseTemplate = [
{
name: "password",
validation: [
{ rule: "minLength", value: 16 },
{ rule: "alphaNumeric" }
]
}
];
// Startup customer: relaxed validation
const startupTemplate = [
{
name: "password",
validation: [
{ rule: "minLength", value: 8 }
]
}
];
// Load based on tenant
const template = await getValidationTemplate(tenantId);
const result = new Validator(data).validateTemplate(template);
No code changes. No deployments. Just configuration.
2. Compliance & Regulations
GDPR in EU. Different rules in California. Different rules in Brazil.
// Load rules based on user location
const template = await getValidationForRegion(userCountry);
// EU template includes GDPR-specific validations
// California template includes CCPA requirements
// All without touching code
Compliance team updates rules → Changes go live immediately
3. A/B Testing Validation
Product wants to test if stricter validation improves data quality.
const template = experimentGroup === 'strict'
? await fetch('/templates/strict-validation.json')
: await fetch('/templates/standard-validation.json');
const result = new Validator(data).validateTemplate(template);
Run experiments on validation rules. Measure impact. Iterate.
No engineering time wasted.
4. CMS-Driven Forms
Build an admin panel where product team configures validation.
// Admin creates form in CMS
// Defines validation rules via UI
// Rules saved as JSON in database
// Frontend fetches and applies
const formConfig = await api.getForm(formId);
const result = new Validator(formData).validateTemplate(formConfig.validation);
Product team owns validation. Engineering team builds once.
Built-In Internationalization
Every rule supports multiple languages out of the box.
{
"name": "email",
"validation": [
{
"rule": "required",
"message": {
"en": "Email is required",
"es": "El email es requerido",
"fr": "L'email est requis",
"de": "E-Mail ist erforderlich"
}
}
]
}
One template. Multiple languages. Zero code duplication.
Nested Object Validation
Dot notation for deep validation.
[
{
"name": "user.profile.email",
"validation": [
{ "rule": "email" }
]
},
{
"name": "user.address.zipCode",
"validation": [
{ "rule": "regex", "value": "^[0-9]{5}$" }
]
}
]
Clean. Readable. No complex nesting.
Conditional Validation
Validate based on other field values.
[
{
"name": "payment_method",
"validation": [
{ "rule": "required" },
{ "rule": "in", "value": ["credit_card", "paypal"] }
]
},
{
"name": "credit_card_number",
"validation": [
{
"rule": "requiredIf",
"value": ["payment_method", "credit_card"]
},
{
"rule": "minLength",
"value": 16
}
]
}
]
Dynamic validation logic. Still just JSON.
Version Control for Validation
Track validation changes like any other data.
CREATE TABLE validation_templates (
id UUID PRIMARY KEY,
name VARCHAR(255),
template JSONB,
version INTEGER,
created_at TIMESTAMP,
created_by VARCHAR(255)
);
Audit trail:
Who changed validation rules?
When?
What changed?
Rollback to previous version instantly
The Architecture
┌──────────────────┐
│ Admin Panel │ ← Product team configures rules
└────────┬─────────┘
│
↓
┌──────────────────┐
│ Database │ ← Store templates as JSON
└────────┬─────────┘
│
↓
┌──────────────────┐
│ API Endpoint │ ← Serve templates
└────────┬─────────┘
│
↓
┌──────────────────┐
│ Frontend/API │ ← Fetch & validate
└──────────────────┘
Separation of concerns:
Business logic (validation rules) = Configuration
Application logic (how to validate) = Code
Comparison: The Old Way vs The New Way
Changing Password Requirements
Old Way (Joi/Zod):
- Open IDE
- Find validation file
- Modify code
- Write tests
- Create PR
- Code review
- Merge
- Deploy
- Monitor Time: 2-3 days People involved: 2-3 developers Risk: High (code changes)
New Way (@teonord/validator):
- Update JSON in database
- Done Time: 2 minutes People involved: 1 product manager Risk: Low (configuration change, instant rollback)
Real Production Example
// Lambda function
export const handler = async (event) => {
const data = JSON.parse(event.body);
// Load validation template from DynamoDB
const template = await dynamodb.get({
TableName: 'ValidationTemplates',
Key: { formId: event.pathParameters.formId }
});
// Validate
const result = new Validator(data).validateTemplate(template.rules);
if (!result.isValid) {
return {
statusCode: 400,
body: JSON.stringify({ errors: result.errors })
};
}
// Process valid data
await processForm(data);
return {
statusCode: 200,
body: JSON.stringify({ success: true })
};
};
Update validation rules → No deployment needed
Why This Matters
Traditional validation libraries:
- Validation = Code
- Changes require deployment
- Developers are bottleneck
- Hard to A/B test
- No runtime flexibility
@teonord/validator templates:
- Validation = Configuration
- Changes are instant
- Product team can iterate
- Easy to experiment
- Complete runtime flexibility
The Paradigm Shift
Stop thinking: "I need to write validation code"
Start thinking: "I need to configure validation rules"
Getting Started
npm install @teonord/validator
Create your first template:
[
{
"name": "email",
"validation": [
{
"rule": "required",
"message": { "en": "Email is required" }
},
{
"rule": "email",
"message": { "en": "Invalid email format" }
}
]
}
]
Use it:
import { Validator } from '@teonord/validator';
const template = require('./validation-template.json');
const result = new Validator(formData).validateTemplate(template);
That's it.
Advanced: Dynamic Rule Loading
class ValidationService {
async validate(formId, data) {
// Load from cache first
let template = await redis.get(`validation:${formId}`);
if (!template) {
// Load from database
template = await db.getValidationTemplate(formId);
// Cache for 1 hour
await redis.set(`validation:${formId}`, template, 'EX', 3600);
}
return new Validator(data).validateTemplate(template);
}
}
Fast. Flexible. Cacheable.
Who Should Use This?
✅ SaaS platforms with multiple tenants
✅ Enterprise apps with complex compliance
✅ International products needing multi-language validation
✅ Rapid iteration teams doing A/B testing
✅ Low-code platforms where non-devs configure forms
✅ API-first architectures needing runtime flexibility
The Bottom Line
Validation rules change more often than your code.
So why are they in your code?
@teonord/validator's template API separates validation logic from application code.
Result:
- Faster iteration
- Less deployment risk
- Product team autonomy
- Better compliance
- Easier A/B testing
- True multi-tenancy
Try It Today
npm install @teonord/validator
Documentation: @teonord/qrdrobe
Stop deploying validation changes.
Start configuring them.
One More Thing
This isn't just about validation.
It's about rethinking what belongs in code vs configuration.
Validation rules are business logic.
Business logic changes frequently.
Frequently changing things shouldn't require deployments.
@teonord/validator gets this right.
What will you build when validation is just JSON?
Written by a developer who's tired of deploying validation changes.
Want to see this in action? Drop a comment and I'll show you a real production setup.
Give feedback to improve this answer.
Top comments (0)