Check out our talk at Remix Conf!

Magically create forms
+ actions in Remix

import { z } from 'zod'
import { makeDomainFunction } from 'remix-domains'
import { formAction, Form } from 'remix-forms'

const schema = z.object({
  firstName: z.string().nonempty(),
  email: z.string().nonempty().email(),
  howYouFoundOutAboutUs: z.enum(['fromAFriend', 'google']),
})

const mutation = makeDomainFunction(schema)(async (values) => value)

export const action: ActionFunction = async ({ request }) =>
  formAction({
    request,
    schema,
    mutation,
    successPath: '/success',
  })

export default () => <Form schema={schema} />

This tiny code creates the form below ๐Ÿ‘‡๐Ÿฝ

All type-safe, with client + server validations, a11y, pending UI, and focus management

(Go ahead, try it with JS disabled as well ๐Ÿ˜‰)

100% customizable UI

Customize everything without losing our accessible defaults.

Single source of truth

Write your schema once and derive everything else from it.

Bulletproof DX

100% typed to your schema. Goodbye typos, hello autocomplete!

Server-side wiring

Perform secure server-side mutations with zero boilerplate.

Fullstack validation

Validate everything both on the client and the server.

Focus management

Focus on the first field with error even for server-side failures.