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 🙏

© 2026 – Pkg Stats / Ryan Hefner

svelte5-form

v0.0.3

Published

Svelte 5 form library

Readme

Svelte 5 Form Lib

A lightweight, type-safe form library for Svelte 5 using runes and snippets.

Features

  • ✨ Built for Svelte 5 with runes
  • 🎯 Type-safe form state management
  • 🔄 Nested object and array support
  • ✅ Built-in validation with visual feedback
  • 🎨 Fully customizable styling
  • 📦 Zero dependencies (except Svelte)

Installation

npm install svelte5-form

Quick Start

<script lang="ts">
  import { Form, Input, Select, Textarea } from 'svelte5-form';

  let formData = $state({
    name: '',
    email: '',
    role: '',
    bio: ''
  });

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

<Form
  bind:defaultData={formData}
  onSubmit={handleSubmit}
  requiredProps={['name', 'email']}
  submitText="Submit"
>
  <Input
    label="Name"
    name="name"
    placeholder="Enter your name"
  />
  
  <Input
    label="Email"
    name="email"
    type="email"
    placeholder="[email protected]"
  />
  
  <Select
    label="Role"
    name="role"
    options={[
      { value: 'developer', label: 'Developer' },
      { value: 'designer', label: 'Designer' }
    ]}
  />
  
  <Textarea
    label="Bio"
    name="bio"
    placeholder="Tell us about yourself"
  />
</Form>

Components

Form

Main form wrapper component.

Props:

  • defaultData (bindable) - Form data object
  • onSubmit - Submit handler function
  • requiredProps - Array of required field names (optional)
  • submitText - Submit button text (default: "Submit")
  • submitClass - Custom submit button classes
  • class - Custom form classes
  • loading - Show loading state (optional)
  • schema - Validation schema (optional)

Input

Text input component with label support.

Props:

  • name - Field path (supports nested: "user.name" or "items[0].title")
  • label - Input label
  • type - Input type (default: "text")
  • placeholder - Placeholder text
  • class - Custom input classes
  • labelClass - Custom label classes
  • required - Show required indicator

Example:

<Input
  label="First Name"
  name="firstName"
  placeholder="John"
  required
/>

<!-- Nested object -->
<Input
  label="Street Address"
  name="address.street"
/>

<!-- Array item -->
<Input
  label="First Item"
  name="items[0].name"
/>

Select

Dropdown select component.

Props:

  • name - Field path
  • label - Select label
  • options - Array of { value, label } objects
  • placeholder - Placeholder option text
  • class - Custom select classes
  • labelClass - Custom label classes
  • required - Show required indicator

Example:

<Select
  label="Country"
  name="country"
  placeholder="Select a country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'ca', label: 'Canada' }
  ]}
  required
/>

Textarea

Multi-line text input component.

Props:

  • name - Field path
  • label - Textarea label
  • placeholder - Placeholder text
  • rows - Number of rows (default: 4)
  • class - Custom textarea classes
  • labelClass - Custom label classes
  • required - Show required indicator

Example:

<Textarea
  label="Description"
  name="description"
  placeholder="Enter a description..."
  rows={6}
/>

Checkbox

Checkbox input component.

Props:

  • name - Field path
  • label - Checkbox label
  • class - Custom checkbox classes
  • labelClass - Custom label classes

Example:

<Checkbox
  label="Accept terms and conditions"
  name="acceptTerms"
/>

Advanced Usage

Nested Objects and Arrays

The library supports deep nested paths using dot notation and array indices:

<script>
  let formData = $state({
    user: {
      profile: {
        name: '',
        email: ''
      }
    },
    hobbies: ['', '']
  });
</script>

<Form bind:defaultData={formData} onSubmit={handleSubmit}>
  <Input name="user.profile.name" label="Name" />
  <Input name="user.profile.email" label="Email" />
  
  <Input name="hobbies[0]" label="First Hobby" />
  <Input name="hobbies[1]" label="Second Hobby" />
</Form>

Custom Validation

<script>
  function handleSubmit(data) {
    // Custom validation
    if (data.password !== data.confirmPassword) {
      alert('Passwords do not match');
      return;
    }
    
    // Submit to API
    fetch('/api/register', {
      method: 'POST',
      body: JSON.stringify(data)
    });
  }
</script>

<Form
  bind:defaultData={formData}
  onSubmit={handleSubmit}
  requiredProps={['email', 'password', 'confirmPassword']}
>
  <!-- form fields -->
</Form>

Loading State

<script>
  let isSubmitting = $state(false);
  
  async function handleSubmit(data) {
    isSubmitting = true;
    try {
      await api.post('/submit', data);
    } finally {
      isSubmitting = false;
    }
  }
</script>

<Form
  bind:defaultData={formData}
  onSubmit={handleSubmit}
  loading={isSubmitting}
>
  <!-- form fields -->
</Form>

Custom Styling

<Form
  bind:defaultData={formData}
  onSubmit={handleSubmit}
  class="max-w-2xl mx-auto p-6"
  submitClass="bg-blue-500 hover:bg-blue-600 text-white px-6 py-3"
  submitText="Create Account"
>
  <Input
    name="username"
    label="Username"
    class="border-2 border-gray-300 rounded-lg p-3"
    labelClass="text-sm font-semibold text-gray-700"
  />
</Form>

API Reference

Store Functions

import { getForm, setForm } from 'svelte5-form-manager';

// Get a value from the form
const value = getForm('user.email');

// Set a value in the form
setForm('user.email', '[email protected]');

TypeScript Support

Full TypeScript support with type definitions included:

import type { FormData, FormProps } from 'svelte5-form';

interface MyFormData {
  name: string;
  email: string;
  age: number;
}

let formData = $state({
  name: '',
  email: '',
  age: 0
});

License

MIT