DEV Community

Cover image for We Built a Full-Stack Form Validation Library (And It's Open Source! and Framework independent)
Tsem Idriss Terrance
Tsem Idriss Terrance

Posted on

We Built a Full-Stack Form Validation Library (And It's Open Source! and Framework independent)

After months of wrestling with forms across multiple projects, my team and I decided enough was enough. Today, I'm excited to share Veli - our first open-source project that reimagines how developers handle form validation.

The Problem We Kept Running Into
Picture this: You're building a web application that needs user registration, contact forms, and data entry screens. The typical workflow looks something like:

  • Install React Hook Form (or Formik)
  • Add Yup or Zod for validation
  • Write CSS or install a UI library for styling
  • Copy-paste your validation rules to the backend
  • Add security checks manually
  • Realize your phone validation doesn't support African numbers
  • Fix bugs in both frontend AND backend

Sound familiar? We were tired of this dance.

What We Built Instead
Veli is a full-stack form validation library that handles everything from a single source of truth. Here's what makes it different:

🎯 True Full-Stack Validation
Write your rules once, use them everywhere:

  1. Frontend (HTML attributes - no JS required!)
<form id="myForm" data-veli-design="classic">
  <div class="veli-field-wrapper">
    <label>Name</label>
    <input 
      type="text" 
      name="username" 
      data-veli-rules='{"type":"text", "name":"username", "minChar":"3", "required":"true"}' 
    />
    <span class="veli-error"></span>
  </div>
  <button type="submit">Submit</button>
</form>
Enter fullscreen mode Exit fullscreen mode
  1. Backend (Node js, express etc...)
const schema =  [
    {
      value: "user@example.com",
      rules: {type: "email", name: "email", provider: "gmail"},
    },
    {
      value: "password123",
      rules: {
        type: "password",
        name: "password",
        minLen: "8@@Password too short", //if password is not 8, show error `Password too short(this is custom error and it overides the default color)`
      },
    },
  ];

const result = validate(schema)
Enter fullscreen mode Exit fullscreen mode

No duplication. No sync issues. One schema, everywhere.

πŸ”’ Security Built-In
Veli includes a security scanner that checks for common vulnerabilities:

  • XSS (Cross-Site Scripting)
  • SQL Injection
  • NoSQL Injection
  • Path Traversal
  • Token Leakage
const scanner = new Scanner({strictMode: true});
//scan any form of thread (xss, sql injection etc....)
const result = scanner.scanAll([
  {name: "email", value: "user@example.com", type: "email"},
  {
    name: "comment",
    value: "<script>alert(1)</script>",
    type: "html",
    allowedTags: ["p"],
  },
]);

//scan only sql injection
const result2 = scanner.scan([
  {name: "email", value: "user@example.com", type: "email"},
  {
    name: "comment",
    value: "<script>alert(1)</script>",
    type: "html",
    allowedTags: ["p"],
  },
], 'sqlInjection');
Enter fullscreen mode Exit fullscreen mode

🌍 Africa-First Phone Validation
We built proper phone number validation for 26 African countries, including:

  • cameroon
  • ghana
  • nigeria
  • southafrica
  • uganda
  • zimbabwe
  • kenya
  • tanzania
  • egypt
  • algeria
  • morocco
  • ivorycoast
  • ethiopia
  • angola
  • senegal
  • zambia
  • malawi
  • rwanda
  • botswana
  • namibia
<div class="veli-field-wrapper">
  <label>Phone</label>
  <input
    type="tel"
    name="phone"
    data-veli-rules='{"type":"tel","name":"phone","country":"cameroon"}' //accepts only phone numbers from cameroon
    placeholder="237679587645"
  />
  <span class="veli-error"></span>
</div>
Enter fullscreen mode Exit fullscreen mode

No more regex nightmares for international phone formats.

🎨 Beautiful UI Out of the Box
Three pre-built themes included:

  1. Classic
<form data-veli-design="classic">
  <!-- fields -->
</form>

<!-- field structure -->

<div class="veli-field-wrapper">
  <label>Field Label</label>
  <input type="text" name="fieldname" data-veli-rules="..." />
  <span class="veli-error"></span>
</div>
Enter fullscreen mode Exit fullscreen mode
  1. Floating Labels
<form data-veli-design="floating-label">
  <!-- fields -->
</form>

<!-- field structure -->

<div class="veli-field-wrapper">
  <input type="text" name="fieldname" placeholder=" " data-veli-rules="..." />
  <label>Field Label</label>
  <span class="veli-error"></span>
</div>
Enter fullscreen mode Exit fullscreen mode
  1. Ifta Label(IOS inspired)
<form data-veli-design="ifta-label">
  <!-- fields -->
</form>

<!-- field structure -->

<fieldset class="veli-field-wrapper">
  <legend>Field Label</legend>
  <input type="text" name="fieldname" data-veli-rules="..." />
  <span class="veli-error"></span>
</fieldset>
Enter fullscreen mode Exit fullscreen mode

You can contumise input colors by adding the following anywhere in your code

import {VeliConfig} from "@gd3v/veli";

VeliConfig({
  colors: {
    error: "#d32f2f",
    success: "#388e3c",
    warning: "#f57c00",
    info: "#1976d2",
  },
});
Enter fullscreen mode Exit fullscreen mode

Complete Example

  <body>
    <div id="container">
    <form id="contactForm" data-veli-design="floating-label" data-veli-lang="en">
      <h1>Contact Us</h1>

      <div class="veli-field-wrapper">
        <input type="text" name="fieldname" placeholder=" " data-veli-rules='{"type":"text","name":"fullname","minChar":"2"}' />
        <label>Field Label</label>
        <span class="veli-error"></span>
      </div>

      <div class="veli-field-wrapper">
        <input type="email" name="email" placeholder=" " data-veli-rules='{"type":"email","name":"email", "provider":"gmail"}' />
        <label>Email</label>
        <span class="veli-error"></span>
      </div>


      <div class="veli-field-wrapper">
        <input type="tel" name="phone" placeholder=" " data-veli-rules='{"type":"tel","name":"phone","country":"cameroon"}' />
        <label>Phone</label>
        <span class="veli-error"></span>
      </div>


      <button type="submit">Submit</button>
    </form>
   </div>
    <script type="module" src="https://cdn.jsdelivr.net/npm/@gd3v/veli@latest/dist/veli.js">

    //getting validation response
    const form = document.getElementById('contactForm');
    form.addEventListener('onCompleteValidation', () => {
       const result = validationResponse.contactForm;
       console.log(result); // { status: true/false, values: {...}}
    });

</script>
  </body>
Enter fullscreen mode Exit fullscreen mode

Veli form validation in action - showing real-time error messages for invalid email and password fields with red error text below inputs

Developer Experience Features
Veli comes with a React hooks-like API and Watcher that feels familiar:

- isDirty() β†’ boolean
- isValid() β†’ boolean
- getCurrentValues() β†’ object
- getDirtyFields() β†’ object
- reset() β†’ void
- on(event, callback) β†’ unsubscribe function
- off(event, callback) β†’ void
Enter fullscreen mode Exit fullscreen mode

Technical Details

  • Zero dependencies - No bloat
  • Framework agnostic - Works with React, Vue, Svelte, vanilla JS, Node.js
  • TypeScript support - Full type inference
  • 35KB gzipped - Smaller than most validation libraries alone
  • Tree-shakeable - Only bundle what you use

What We Learned
Building Veli taught us invaluable lessons:

  • Building for real-world use cases - We used our own pain points as a guide
  • API design matters - Spent weeks iterating on the developer experience
  • Documentation is crucial - Built a live editor so devs can try before installing
  • Shipping beats perfection - We launched with v1.0 despite wanting to add more features
  • Community matters - Early feedback shaped the direction significantly

Try It Out
πŸ“š Documentation & Live Editor: https://veli.gd3v.com
πŸ’» GitHub: https://github.com/gd3v-cameroon/veli

We Need Your Feedback
This is our first open-source project, and honestly, it's nerve-wracking to put it out there. But Veli is already solving real problems for our team at Eschuul, and we believe it can help yours too.
If you:

  • Work with forms regularly
  • Are tired of duplicating validation logic
  • Need better security out of the box
  • Want proper African phone number support
  • Value developer experience

Give Veli a try and let us know what you think!
If you find it useful, a ⭐ on GitHub would mean the world to us.

What's Next?
We have big plans:

  • More African country support
  • Integration with popular frameworks (Next.js, Nuxt, SvelteKit)
  • Visual form builder
  • Advanced field types (file uploads, date ranges, etc.)
  • i18n support for error messages

This is just the beginning. Join us on this journey!

Questions? Feedback? Feature requests? Drop them in the comments below or open an issue on GitHub. We'd love to hear from you!

Built with ❀️ by the GD3V team

Top comments (0)