Formshape
Type-safe form validation for SvelteKit Remote Functions using Standard Schema compatible validators.
Install / Use
/learn @didier/FormshapeREADME
formshape
Type-safe form validation for SvelteKit Remote Functions using Standard Schema compatible validators.
Features
- 🎯 Works with any Standard Schema compatible library (Zod, Valibot, Arktype, etc.)
- 🔒 Full type safety with automatic type inference
- ⚡ Preserves all SvelteKit form features (progressive enhancement,
enhance,buttonProps, etc.) - 📦 Lightweight with zero dependencies (besides your validator)
- 🎭 Same API as SvelteKit's
formfunction
Installation
npm install formshape
# or
pnpm add formshape
Usage
1. Create a validated function in your server code
// src/routes/contact/data.remote.ts
import { z } from 'zod'
import { form } from '$app/server'
import { createValidated } from 'formshape'
// Create the validated function using your app's form function
const validated = createValidated(form)
// Define your schema
const contactSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
email: z.string().email('Invalid email address'),
message: z.string().min(10, 'Message must be at least 10 characters')
})
// Create your form handler - data is fully typed!
export const submitContact = validated(contactSchema, async (data) => {
// data is typed as { name: string; email: string; message: string }
await sendEmail(data)
return {
success: true,
message: 'Thank you for your message!'
}
})
2. Use it in your Svelte component
<script lang="ts">
import { submitContact } from './data.remote.js'
</script>
<form {...submitContact}>
<input name="name" />
{#if submitContact.result && 'errors' in submitContact.result}
<span>{submitContact.result.errors.name?.join(', ')}</span>
{/if}
<input name="email" type="email" />
{#if submitContact.result && 'errors' in submitContact.result}
<span>{submitContact.result.errors.email?.join(', ')}</span>
{/if}
<textarea name="message"></textarea>
{#if submitContact.result && 'errors' in submitContact.result}
<span>{submitContact.result.errors.message?.join(', ')}</span>
{/if}
<button>Send Message</button>
</form>
{#if submitContact.result?.success === true}
<p>{submitContact.result.message}</p>
{/if}
How it works
The createValidated function takes your app's form function and returns a validated function. This approach ensures that the package works correctly when installed from npm, as it uses your app's SvelteKit context rather than trying to import from $app/server directly.
When validation fails, the function returns:
{
success: false,
errors: Record<string, string[]>,
data: unknown // The original form data
}
When validation succeeds, your handler is called with the validated data and its return value is passed through.
Using with enhance
The validated form maintains full compatibility with SvelteKit's enhance:
<form
{...submitContact.enhance(async ({ submit }) => {
const result = await submit()
// Handle the result
})}
>
<!-- form fields -->
</form>
Using with other validators
Any Standard Schema compatible validator works:
Valibot
import * as v from 'valibot'
const schema = v.object({
email: v.pipe(v.string(), v.email())
})
export const myForm = validated(schema, async (data) => {
// ...
})
Arktype
import { type } from 'arktype'
const schema = type({
email: 'email',
age: 'number > 0'
})
export const myForm = validated(schema, async (data) => {
// ...
})
API
createValidated(form)
Creates a validated function using your app's form function.
- Parameters:
form: The form function from$app/server
- Returns: A
validatedfunction
validated(schema, handler)
Creates a form handler with validation.
- Parameters:
schema: A Standard Schema compatible validatorhandler: An async function that receives validated data
- Returns: A
RemoteFormobject (same as SvelteKit'sform)
License
MIT
Related Skills
node-connect
338.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
338.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.6kCommit, push, and open a PR
