NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Forms for Laravel

Install
composer require roundly-consulting/forms-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

A native form engine for Laravel. Define multi-step forms — forms, groups and fields — as data in your database, validate input against per-field rules, and store every submission, tied to whoever sent it. Build forms with a fluent builder or sync them from config, save and resume drafts, read answers back typed, accept file uploads as private media and route submissions to the reviewers you name. MIT licensed and built only on Laravel and Roundly’s own open-source packages — no third-party form vendors.

What you get

Forms as data

Forms, groups (steps) and fields live in your database — change a form without shipping code or redeploying.

Fluent builder & config sync

Define a whole form in one transactional call, edit it with a diffing updater, or declare it in config and run forms:sync.

Conditional validation

Per-field Laravel rules, custom messages, and fields that are shown or required only when another answer matches.

Drafts & closed forms

Save and resume partial submissions, finalize with full validation, and reject submissions to private or expired forms.

Typed answers & uploads

Answers read back as int, bool, dates and arrays; file fields store uploads as private media with signed URLs.

Submission review

Route a whole submission to the reviewers you name — unanimous, any, quorum or weighted — with status mirrored back.

Facade, DI or actions

Call the Forms facade, inject FormsManager or run single-purpose actions — Forms::fake() records every call and still performs it.

Documentation

Installation

Install via Composer, publish and run the migrations (including the dependency packages’), and optionally publish config and translations.

Configuration

Every config key and its default — swappable models, sender key type, field resolvers, typed field types, media uploads and reviews.

The Forms facade

The whole API on one facade — define, find, validate, submit, draft, finalize, read and review forms, plus fluent builders and handles.

DI and actions

Prefer explicit dependencies? Inject FormsManager for the same API, or call the single-purpose actions behind each facade method.

Form structure

Forms hold ordered groups (steps), groups hold fields. Create them as plain Eloquent models and read the dotted field path.

Fluent form builder

Define a whole form — groups and fields — in one transactional call with Forms::define(), typed shortcuts and custom messages.

Conditional fields

Show or require a field only when another answer matches — hidden fields are skipped by validation automatically.

Validating & submitting

Find a form, validate request input against each field’s rules, and store a submission for every field under one reference uuid.

Drafts (save & resume)

Save a partial submission without validation, resume it by uuid, and finalize it later with full validation.

Reading submissions

Read submissions back as one keyed, typed answer set each — filtered by sender, uuid or review outcome — or fetch one by its uuid.

Editing forms

Diff a new definition against the stored structure and save only what changed — events fire only for changed records.

Typed field values

Each field type maps to a value type, so answers read back as int, bool, dates or arrays and mismatches fail validation.

File uploads

file and image fields store uploads as private media on the submission row — image variants, passthrough files and signed URLs.

Submission review

Route a whole submission to the reviewers you name — unanimous, any, quorum or weighted — with its status mirrored back.

The HasForms trait

Give your user (or any sender) model a submissions relation plus submitTo() and draftTo() shortcuts.

Declarative forms

Declare forms in config/forms.php and sync them into the database idempotently with php artisan forms:sync.

Resolvers & autofill

Control how a field type reads from the request and from storage with a custom resolver, and pre-fill fields with Autofill classes.

API resources

Render a form and its groups and fields as JSON for SPA or mobile frontends with the bundled JsonResources.

Events

React to submissions, structure changes and review outcomes — FormSubmitted, Form/Group/Field lifecycle and review events.

Exceptions

Package-specific, catchable exceptions — all extending FormsException — with translatable messages you can override.

Models, scopes & soft deletes

Query scopes for public, active and expired forms, recoverable soft deletes, and swapping any model for your own subclass.

Artisan commands

Sync config-defined forms with forms:sync and inspect the package setup in php artisan about.

Testing

Assert form activity with Forms::fake() — a recording fake that still performs — plus InteractsWithForms helpers, Pest matchers and factories.

Requirements

PHP 8.4+ and Laravel 12 or 13; enums, attributes, media library and approvals packages install automatically.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.