npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

vue-form-use

v0.6.3

Published

Performant, flexible and extensible forms with easy-to-use validation for Vue 3

Readme

vue-form-use

npm version npm downloads bundle License

Performant, flexible and extensible forms with easy-to-use validation for Vue 3.

Features

  • 🚀 Performant - Minimal re-renders and optimized form state management
  • 📦 Lightweight - Small bundle size with zero dependencies (except Vue)
  • 🔒 Type-safe - Full TypeScript support with excellent type inference
  • 🎯 Flexible - Works with any form library and custom components
  • 🔧 Extensible - Easy to integrate with validation libraries
  • 🎨 Composable - Built with Vue 3 Composition API

Installation

npm i vue-form-use
# or
pnpm add vue-form-use
# or
yarn add vue-form-use

Usage

Basic Example

<script setup lang="ts">
import { useForm } from 'pkg-placeholder'

const form = useForm({
  defaultValues: {
    username: '',
  },
})

const onSubmit = form.handleSubmit((data) => {
  console.log('🚀 Submit Data: ', data)
})
</script>

<template>
  <form @submit.prevent="onSubmit">
    <input :="form.register('username', { required: 'username field cannot be empty!' })">
    <span v-if="form.errors.username">errors: {{ form.errors.username?.message }}</span>
    <button type="submit">
      submit
    </button>
  </form>
</template>

Using Resolver Options

We also support schema-based form validation with Yup, Zod , Superstruct & Joi, where you can pass your schema to useForm as an optional config. It will validate your input data against the schema and return with either errors or a valid result.

<script setup lang="ts">
import { FieldError, useForm } from 'vue-form-use'
import { yupResolver } from 'vue-form-use/resolver/yup'
import * as yup from 'yup'

const schema = yup.object({
  name: yup.string().required('Name is required'),
  email: yup.string().email('Invalid email').required('Email is required'),
})

const form = useForm({
  defaultValues: { name: '' },
  resolver: yupResolver(schema),
})

const onSubmit = form.handleSubmit((data) => {
  console.log(data)
})
</script>

<template>
  <form @submit="onSubmit">
    <input :="form.register('name')" placeholder="Name">
    {{ form.errors.name?.message }}
    <input :="form.register('email')" placeholder="Email">
    {{ form.errors.email?.message }}
    <button type="submit">
      Submit
    </button>
  </form>
</template>

Using Controller Component

For more complex scenarios or when you need fine-grained control, you can use the Controller component:

<script setup lang="ts">
import { Controller, useForm } from 'vue-form-use'

const form = useForm({
  defaultValues: {
    name: '',
    email: '',
  },
})

const onSubmit = form.handleSubmit((data) => {
  console.log(data)
})
</script>

<template>
  <form @submit="onSubmit">
    <Controller v-slots="{ field }" :control="form.control" name="name">
      <input v-model="field.value" placeholder="Name">
    </Controller>

    <Controller v-slots="{ field }" :control="form.control" name="email">
      <input v-model="field.value" placeholder="Email">
    </Controller>

    <button type="submit">
      Submit
    </button>
  </form>
</template>

Form State

Access form state including errors, validation status, and more:

<script setup lang="ts">
import { useForm } from 'vue-form-use'

const form = useForm({
  defaultValues: {
    email: '',
  },
})

// Access form values (reactive)
const emailValue = computed(() => form.values.email)

// Access form state
const isDirty = computed(() => form.status.isDirty)
const isValid = computed(() => form.status.isValid)
const isSubmitting = computed(() => form.status.isSubmitting)
</script>

<template>
  <form>
    <input :="form.register('email')">
    <p v-if="form.errors.email">
      {{ form.errors.email.message }}
    </p>
    <!-- directly using field values, it has responsiveness -->
    {{ form.values.email }}
    <!-- or use a computed property -->
    {{ emailValue }}
    <!-- access form status -->
    <p>Is Dirty: {{ isDirty }}</p>
    <p>Is Valid: {{ isValid }}</p>
  </form>
</template>

Reset Form

Reset the form to its default values:

<script setup lang="ts">
import { useForm } from 'vue-form-use'

const form = useForm({
  defaultValues: {
    name: '',
    email: '',
  },
})
</script>

<template>
  <form>
    <input :="form.register('name')">
    <input :="form.register('email')">
    <button type="button" @click="form.reset()">
      Reset
    </button>
  </form>
</template>

API

useForm

The main composable for managing form state.

Parameters

function useForm(props: UseFormProps): UseFormReturn
  • defaultValues - Default values for the form (can be async function)
  • values - Controlled form values
  • mode - Validation mode: 'onSubmit' | 'onBlur' | 'onChange' | 'onTouched' | 'all' (default: 'onSubmit')
  • reValidateMode - Re-validation mode: 'onChange' | 'onBlur' | 'onSubmit' (default: 'onChange')
  • disabled - Disable the entire form
  • errors - External controlled errors
  • resetOptions - Options for reset behavior (keepDirtyValues, keepErrors, etc.)
  • resolver - Validation resolver function
  • context - Custom context object passed to resolver
  • shouldFocusError - Focus the first error field on submit (default: true)
  • shouldUnregister - Unregister fields on unmount (default: false)
  • shouldUseNativeValidation - Use native HTML5 validation
  • criteriaMode - Error criteria mode: 'firstError' | 'all'

Returns

  • values - Reactive form values (the actual form data)
  • state - Form state object containing:
    • isDirty, isValid, isSubmitting, etc.
    • fields - Field-level state for each field (invalid, isDirty, isTouched, etc.)
  • control - Form control instance
  • errors - Field errors object
  • register - Register a field
  • unregister - Unregister a field
  • handleSubmit - Handle form submission
  • reset - Reset the form
  • resetField - Reset a specific field
  • update - Update form values
  • trigger - Trigger validation
  • setError - Set field error manually
  • clearError - Clear field error
  • focus - Focus a field

Controller

A component for managing individual form fields with scoped slots.

Props

  • name - Field name (typed)
  • control - Form control instance from useForm

Slots

  • default - Receives { field, state } where:
    • field - Field props (value, onChange, onBlur, etc.)
    • state - Form state

useController

A composable alternative to the Controller component.

const controller = useController({
  control: form.control,
  name: 'fieldName',
})

TypeScript

Full TypeScript support with excellent type inference:

interface FormValues {
  name: string
  email: string
  age: number
}

const form = useForm<FormValues>({
  defaultValues: {
    name: '',
    email: '',
    age: 0,
  },
})

// Type-safe field access
form.values.name // string
form.values.email // string
form.values.age // number

// Access form status
form.status.isDirty // boolean
form.status.isValid // boolean
form.status.fields.name.isDirty // boolean
form.status.fields.name.error // FieldError | undefined

License

MIT License © 2024-PRESENT Hairyf