DEV Community

tu6ge
tu6ge

Posted on • Edited on

vue-uform: A Component-First, Unstyled Form Validation Library for Vue 3

1. The Problem with Most Form Libraries
When building forms in Vue, I’ve often found that existing solutions fall into one of two camps:

  1. Overly opinionated – They ship with a lot of styling and layout assumptions that don’t match your UI framework or design system.
  2. Too much boilerplate – Setting up form values, validation rules, and event handlers requires a ton of JS/TS code for even basic forms.

If you’ve worked with frameworks like VeeValidate or FormKit, you know they are powerful, but sometimes you just want complete control over markup and styling, while still getting a declarative, maintainable form API.

2. Enter vue-uform
vue-uform is my attempt to solve these pain points.
It’s a unstyled, component-first form library for Vue 3.

Key ideas:

  • Component-first API – Fields, forms, and submit buttons are all Vue components.
  • No built-in styles – You write your own HTML & CSS or use your favorite UI framework (Element Plus, Naive UI, Vuetify…).
  • Composable validation – Built-in rules for common needs, plus an easy API for custom validators.
  • f-model directive – A tiny Vite plugin that gives you v-model-like syntax for form fields, without repetitive boilerplate.

3. Quick Start Example

<script setup>
const formValues = { username: '', password: '' }

function doLogin(data) {
  console.log('Form submitted:', data)
}
</script>

<template>
  <u-form :values="formValues" @submit="doLogin">
    <u-field name="username" label="Username" validation="required" v-slot="{ value, update }">
      <input f-model />
    </u-field>

    <u-field name="password" label="Password" validation="required|min:6" v-slot="{ value, update }">
      <input type="password" f-model />
    </u-field>

    <u-submit>Login</u-submit>
  </u-form>
</template>
Enter fullscreen mode Exit fullscreen mode

Here, <u-field> handles:

  • Tracking the field’s value
  • Running validation rules
  • Passing data to the form

The f-model directive is provided by @vue-uform/vite-plugin, which compiles:

<input f-model />
Enter fullscreen mode Exit fullscreen mode

into

<input :value="value" @input="$event => update($event.target.value)" />
Enter fullscreen mode Exit fullscreen mode

4. Built-in Validation Rules

Out of the box, you get:
required, number, email, between, max, min, alpha, alphanumeric, starts_with, ends_with, url, and more.

Example custom validator with parameters:

<script setup>
import { FieldNode } from 'vue-uform'

function minWords(node: FieldNode, min: number) {
  const words = String(node.value.value).trim().split(/\s+/).length
  return words >= min || `Please enter at least ${min} words.`
}
</script>

<template>
  <u-field
    name="bio"
    validation="min_words:5"
    :rules="{ min_words: minWords }"
    v-slot="{ value, update }"
  >
    <textarea f-model></textarea>
  </u-field>
</template>
Enter fullscreen mode Exit fullscreen mode

5. Why This Works Well

  • UI Freedom – Works equally well with native HTML inputs or from Naive UI, from Element Plus, etc.
  • Declarative Structure – The form is defined entirely in the template; minimal JS/TS logic is needed.
  • Extensible – Add custom validation logic without hacking the core.
  • Consistent API – Every field gets the same slot props (value, update, hasError).

6. Installation

pnpm install vue-uform
pnpm install @vue-uform/vite-plugin -D
Enter fullscreen mode Exit fullscreen mode
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uForm from '@vue-uform/vite-plugin'

export default defineConfig({
  plugins: [vue(), uForm()],
})
Enter fullscreen mode Exit fullscreen mode
// main.ts
import { plugin } from 'vue-uform'

createApp(App).use(plugin).mount('#app')
Enter fullscreen mode Exit fullscreen mode

7. Link

GitHub: https://github.com/tu6ge/vue-uform
StackBlitz: https://stackblitz.com/~/github.com/tu6ge/vue-uform-example

Closing Thoughts

If you like the flexibility of writing your own HTML & CSS but want the convenience of declarative form handling and validation, vue-uform might be a good fit.
I’d love to hear your feedback, ideas, and PRs.

Top comments (2)

Collapse
 
ash_arutam_3fce868e24bbd6 profile image
Ash Arutam

Good job! Maybe you add themes for css styles?

I also develop ui lib for chats, chotto UI, and Chotto have 3 basic themes. And developer can customize ui with own theme

Collapse
 
tu6ge profile image
tu6ge

I think it would be better without styles, as this would allow users more flexibility and freedom in their usage.