Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laraform Laravel Package

sujan/laraform

LaraForm is a Laravel package for building dynamic, reusable forms with a fluent PHP API. Define fields, validation rules, and layouts in code, then render clean markup. It streamlines form creation for admin panels and CRUD apps, reducing repetitive Blade templates.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish. Pull the package in with Composer and publish its config so you can see the form-definition paths and default options:

composer require sujancse/laraform
php artisan vendor:publish --provider="Sujan\LaraForm\LaraFormServiceProvider"

Check compatibility first. The last release was September 2021, so before wiring it into a real project confirm it installs cleanly against your Laravel version (composer why-not sujancse/laraform is the quickest check). On Laravel 10/11 you may need --ignore-platform-reqs or a fork; if it fails to boot, stop here — do not build on it.

Look at these first, in order:

  1. The published config file — it tells you where YAML/JSON definitions are expected to live and which parser/driver is active.
  2. The package's README examples for a single form — that is the canonical shape of a definition.
  3. The service provider bindings — this is where the builder is registered and where you would swap or extend it.

Your first use case: a static create form. Define the form declaratively instead of chaining $builder->text(...)->select(...) calls:

# resources/forms/contact.yaml
action: /contacts
method: POST
fields:
  name:
    type: text
    label: Full name
    rules: required|max:120
  email:
    type: email
    label: Email
    rules: required|email
  message:
    type: textarea
    label: Message
    rows: 5

Then render it from a Blade view via the package's facade/helper (the exact name is in the README — typically LaraForm::render('contact') or a @laraform('contact') directive). The payoff is that the same file drives both the HTML and the validation rules, so the form definition is a single source of truth.

Implementation Patterns

Definition-per-form, controller-per-action. Keep one YAML/JSON file per logical form and load it by name from the controller. This keeps views dumb:

public function create()
{
    return view('contacts.create', [
        'form' => LaraForm::make('contact'),
    ]);
}

Derive validation from the definition. The strongest reason to use this package over hand-written Blade is that field-level rules live next to the field. In store(), pull the rules out of the definition and feed them to $request->validate(...) rather than duplicating them in a FormRequest. If the package does not expose a rules accessor, add a thin wrapper service that reads the parsed definition — one place to change if the API shifts.

Split definitions into reusable fragments. Most real forms share an address block, a consent checkbox, or audit fields. Keep those as separate YAML files and include/merge them at load time, either via the package's include support or by merging parsed arrays in a small repository class. Avoid copy-pasting field definitions across files; that is where drift and validation mismatches start.

Two-tier definitions: base + per-context overrides. Define a user.base.yaml and then user.create.yaml / user.edit.yaml that override action, method, and field-level readonly/hidden flags. This handles the common create-vs-edit split without duplicating 90% of the schema.

Load JSON when the definition is generated. YAML is nicer for hand-authored forms, but JSON is the better choice when definitions are produced by code (a CMS admin UI, a config export, a tenant-specific form). Both are supported; pick YAML for humans, JSON for machines, and don't mix within one form.

Cache parsed definitions. Parsing YAML on every request is wasted cycles. Wrap the load in Cache::remember("laraform.{$name}", now()->addHour(), fn () => $parser->parse(...)) and clear on deploy. For a handful of small forms this is optional; for a definition loaded on a hot page it is not.

Integrate with existing Blade layouts. Render the form inside your normal layout and pass through wrapper attributes/classes so the generated markup matches your CSS framework. If the package's markup is too opinionated, override its field views via vendor:publish --tag=views rather than post-processing HTML.

Use it for admin/internal CRUD first. The best low-risk adoption is an internal admin screen where the form shape is stable. Keep customer-facing forms on hand-written Blade until you trust the package's escaping and markup.

Gotchas and Tips

It is effectively unmaintained. Last release 2021, zero dependents, 46 stars. Treat it as vendored code: fork it into your org, pin the version, and be prepared to patch it yourself. Do not adopt it for a long-lived product without that plan.

YAML is a parser, not a validator. A malformed definition usually surfaces as a blank form or a confusing exception deep in the builder, not a clear "line 12: bad indent". Validate definitions in a test (parse every file in resources/forms and assert it yields fields) so a typo fails CI, not production.

Never parse user-supplied YAML. If any part of a definition can come from a request (tenant-configured forms, admin JSON paste), you are feeding an untrusted parser and then rendering its output. Whitelist allowed field type values and allowed attributes explicitly; do not pass arbitrary definition keys through to HTML attributes.

Escaping and raw HTML. Declarative builders often have a raw/html field type for embedding markup. Confirm that labels, help text, and option labels are escaped by default, and that only the explicit raw type is unescaped. Test with a label containing <script>.

Method spoofing and CSRF. The definition's method: PUT must emit @method('PUT') and the form must still include @csrf. Check the generated markup for both — missing CSRF tokens here produce 419s that look like session bugs.

Validation rules drift from the field type. A type: email field with rules: required alone will accept garbage. Keep the rule set explicit in the definition; don't assume the field type implies validation.

Attribute naming collisions. Keys like class, name, id, and value in the definition may be interpreted as builder options rather than HTML attributes. When an attribute "doesn't show up", check the package's reserved-key list first.

Debugging tip: dump the parsed definition before rendering. When a field is missing or misrendered, log the array the parser returns and compare it to the YAML. Most issues are at the parse/merge step, not in the renderer.

Extension points to use before forking. The service provider bindings and the field-type registry (if present) are the intended seams. Register a custom field type for your design-system components there; only patch vendor code for genuine bugs.

Upgrade risk is asymmetric. Because there is no active maintainer, a Laravel major upgrade may break the package with no fix coming. Isolate usage behind a small FormRepository/FormRenderer interface in your app so you can swap to a maintained builder (or plain Blade partials) without touching controllers and views.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package