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

Framework Laravel Package

laravel/framework

Laravel is a web application framework with expressive, elegant syntax, offering routing, dependency injection, sessions, caching, migrations, queues, and broadcasting for building robust PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Laravel is a full-stack framework, not a library you bolt onto an existing app. laravel/framework is the core package that arrives transitively — you scaffold a project from the application skeleton and let Composer pull the framework in:

composer create-project laravel/laravel my-app
cd my-app
php artisan about      # confirmation of PHP, drivers, cache, DB, versions
php artisan serve

Laravel 13 requires a modern PHP runtime (8.3+) — verify with php artisan about before debugging anything else.

Where to look first

Path What lives there
routes/web.php, routes/api.php, routes/console.php Entry points; read these to understand the app's surface area
app/Http/Controllers, app/Http/Requests Request handling and validation
app/Models Eloquent models, relationships, casts
config/*.php The only place env() should be called
database/migrations, database/factories, database/seeders Schema and test data
tests/Feature, tests/Unit Pest or PHPUnit suites; run php artisan test
bootstrap/app.php The 11+ style single-file wiring for middleware, exceptions, routing
app/Providers/AppServiceProvider.php Container bindings, model strictness, global config

First use case — a single resource end-to-end, which exercises routing, DI, validation, Eloquent, Blade/JSON and testing in one pass:

php artisan make:model Post -mfsc --requests --resource
php artisan migrate
// routes/web.php
Route::resource('posts', PostController::class);

// app/Http/Controllers/PostController.php
public function store(StorePostRequest $request)
{
    $post = Post::create($request->validated());

    return redirect()->route('posts.show', $post);
}

Then write the feature test before adding a second resource — this is the fastest way to learn the framework's feedback loop:

it('creates a post', function () {
    $this->post(route('posts.store'), ['title' => 'Hello'])
        ->assertRedirect();

    expect(Post::count())->toBe(1);
});

Implementation Patterns

Thin controllers, fat domain. Keep controllers to transport concerns (validate → delegate → respond). Push multi-step logic into action classes or services resolved from the container, so it stays unit-testable and reusable from jobs and commands.

// app/Providers/AppServiceProvider.php
$this->app->bind(PaymentGateway::class, StripeGateway::class);

Constructor-inject the interface; swap the binding in tests. Remember the container also resolves jobs, listeners, commands and middleware — any of them can take dependencies.

Form Requests for validation + authorization. Move authorize() and rules() out of controllers. Validation rules should be explicit and strict — recent releases tightened loose-comparison behaviour in in_array, contains/doesnt_contain and dotted/asterisk input keys, so prefer typed arrays, enums in Rule::in(), and bail where the first failure is sufficient.

Eloquent as a query builder, not a row loader. Eager-load deliberately and constrain eager loads at the point of use:

$posts = Post::query()
    ->with(['author:id,name', 'comments' => fn ($q) => $q->latest()->limit(5)])
    ->whereBinary('slug', $slug)
    ->latest()
    ->paginate(20);

For concurrency-sensitive flows, wrap reads in transactions and use the newer refreshForUpdate() (13.27+) rather than lockForUpdate() on a stale instance. Use inOrderOf() (accepts enums) for deterministic ordering, and whereBinary() when case-sensitivity matters on MySQL/MariaDB.

Queue everything that isn't a response. Jobs are the natural home for slow I/O, notifications and fan-out:

#[TryAgain(3, backoff: [10, 60, 300])]
class SendInvoice implements ShouldQueue
{
    use InteractsWithQueue, Queueable;

    public function handle(): void { /* ... */ }
}

Combine with WithoutOverlapping, job middleware, and unique jobs. Recent releases added a JobReleased event on the worker, totalXSize queue inspection methods, and fixed uniqueness releasing locks the job never acquired — useful if you're building queue dashboards or alerting.

Events and listeners for decoupling. Fire a domain event from the model/action, then queue listeners. Listen to worker lifecycle events (JobReleased, JobProcessing) for observability instead of sprinkling logging through handle().

HTTP and process abstraction over raw cURL. Http::withToken(...)->retry(3, 100)->get(...) plus Http::fake() in tests. Since 13.27, quietly() no longer makes throw() unreachable on process results, and image creation from URLs throws on unsuccessful responses — don't assume silent failure.

Testing patterns that pay for themselves:

Http::fake(['api.example.com/*' => Http::response(['ok' => true])]);
Queue::fake();
Event::fake([InvoiceSent::class]);
Storage::fake('local');

$this->travelTo(now()->setDate(2026, 1, 1));

Use RefreshDatabase for anything touching the DB, factories for state, and Pest datasets for matrixed cases. For queues, prefer Queue::fake() assertions (assertPushed) over executing jobs unless you're specifically testing the job.

Artisan as a first-class interface. php artisan make:* for scaffolding (controllers, requests, policies, tests, casts), scheduled tasks in routes/console.php, and custom commands for ops chores. php artisan pail for live logs, php artisan telescope/horizon when installed for inspection.

Gotchas and Tips

  • Don't composer require laravel/framework directly. Use the laravel/laravel skeleton and let the framework version float within your constraint. Requiring it explicitly is how you end up with a mismatched skeleton.
  • Never patch vendor/. Everything in the framework is overridable: bind an interface, extend a class, or use an extension point (Builder::macro, custom casts, custom validation rules, Model::resolveRelationUsing). If you genuinely need a core change, contribute upstream.
  • env() outside config/ returns null once config:cache runs. This is the single most common "works locally, breaks in prod" bug. Only call env() inside config/*.php, and add new keys to .env.example at the same time.
  • N+1 is silent until it isn't. Enable Model::preventLazyLoading(! app()->isProduction()) and Model::preventSilentlyDiscardingAttributes() in local/staging. For API surface control, be aware maxRelationshipDepth limits nested includes — including the behaviour when it's set to zero, which was fixed to also limit nested includes.
  • Loose comparison and key-parsing rules shift between releases. Asterisks in request/URI query parameters now merge as literal keys, and literal dots are treated literally when rejecting unknown fields. If you rely on Arr::dot-style expansion, retest on upgrade.
  • Pin minor versions when relying on brand-new methods. orWhereKey() was added, reverted (13.26.1) and re-introduced without breaking Builder subclasses (13.27.0). Same caution applies to refreshForUpdate(), whereBinary(), the Cloud facade and the read-through filesystem disk — all recent additions.
  • Queue uniqueness and debounce windows are subtle. A debounced job now starts a new max-wait window after it runs, and the worker no longer force-releases a unique lock the job never acquired. If you built your own lock-around-job logic, reconcile it with the framework's.
  • Read-through disks only move/copy files that exist on the fallback; deleting or stat'ing through a fallback behaves differently than on a plain local disk. Test the fallback path explicitly.
  • Exception messages can leak bindings. Use the query-binding masking option before shipping verbose error pages to anything internet-facing, and keep APP_DEBUG=false in production.
  • Container scoping: singleton bindings are per-process — in Octane or long-running workers, request state (Auth::user(), request()) leaks unless you use scoped() bindings or reset in middleware. Duplicate scoped registrations are now prevented, but the scoping decision is still yours.
  • Route names can be lost if a RouteRegistrar action isn't callable — fixed in 13.27, but if you generate URLs dynamically, assert route() resolves in tests rather than assuming.
  • Upgrade discipline: read changelog/ per minor, run php artisan test plus composer outdated in CI, and apply Rector rules for framework-driven refactors. Laravel's release cadence is fast; skipping several minors turns a 10-minute upgrade into an afternoon.
  • Debug ladder: dump()/dd() → Log::debug() → php artisan pail → DB::listen() for query inspection → Telescope/Horizon for request and job traces. Reach for a debugger before adding echo in a controller.
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.
vento/laravel-airbrake
wfeller/laravel-batch
maco-studios/mage-os-installer
busarm/armie
siberfx/laravel-logger
kfteam1991/dcat-admin
dashed/dashed-laposta
dashed/dashed-ecommerce-montaportal
dashed/dashed-ecommerce-etsy
neohq/string-blade-compiler
log1x/acf-composer
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager