Laravel Getting Started
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
This page is written against Laravel 13.x (13.34.0), checked on 2026-10-05, with the Laravel installer 5.32 and PHP
8.3 to 8.5. Every command and output was captured from a fresh application created with laravel new. Laravel 12
applications look almost the same; the differences are noted. The language itself is covered in the
PHP Reference, and how PHP serves requests in
The PHP Request Model and Servers.
Installing PHP, Composer and the Laravel installer
Laravel needs PHP (8.3 or newer for Laravel 13), Composer, and, for front-end assets, Node.js with npm (or Bun). The
laravel command-line installer creates new applications. Three ways to get all of it:
-
php.new: one command that installs PHP, Composer and the Laravel installer on macOS, Windows or Linux, without a package manager. Re-running it updates them.
-
Laravel Herd: a native development environment for macOS and Windows with PHP, Nginx, Composer, Node and the
laravelcommand included; applications in its "parked" directory are served automatically ashttps://name.test. Herd Pro adds local databases, mail and log viewers. -
Your own PHP and Composer: install the installer with Composer.
# Linux (macOS: .../install/mac/8.5; Windows: a PowerShell one-liner on the installation page)
/bin/bash -c "$(curl -fsSL https://php.new/install/linux/8.5)"
# or, with PHP and Composer already installed
composer global require laravel/installer
laravel --version # Laravel Installer 5.32.0
Docker users can use Laravel Sail instead of a local PHP; see Docker and Sail.
Creating an application
laravel new asks interactively for a starter kit (none, React, Svelte, Vue or Livewire), the authentication
provider (Laravel’s own or WorkOS), the test framework (Pest or PHPUnit), the database, whether to install Laravel
Boost, and whether to run npm install. Every question has a flag, so the command can run unattended:
$ laravel new --help
--database=DATABASE The database driver your application will use. Possible values are: mysql, mariadb, pgsql, sqlite, sqlsrv
--react | --svelte | --vue | --livewire Install a starter kit
--livewire-class-components Generate stand-alone Livewire class components
--workos Use WorkOS for authentication
--teams Install team support
--no-authentication Do not generate authentication scaffolding
--pest | --phpunit Install the Pest or PHPUnit testing framework
--npm | --pnpm | --bun | --yarn | --no-node Install and build front-end dependencies (or not)
--boost | --no-boost Install Laravel Boost to improve AI assisted coding
--git, --github[=…] Initialize a Git repository (and create it on GitHub)
...
$ laravel new bookshelf --pest --database=sqlite --no-node --no-boost --no-interaction
{"success":true,"name":"bookshelf","directory":"/home/ada/code/bookshelf"}
Source: Laravel — Creating an Application and Starter Kits
In non-interactive mode the installer prints only a JSON summary; interactively it shows each step. The starter kits (authentication, a dashboard, and a React, Svelte, Vue or Livewire front end) are covered on Inertia and Starter Kits and Livewire; the rest of this page uses the plain application.
What you get
The installer runs composer create-project laravel/laravel, which copies .env.example to .env, generates the
APP_KEY, creates database/database.sqlite and runs the migrations. The relevant settings of the new .env:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:... # generated by php artisan key:generate: never commit it
APP_DEBUG=true
APP_URL=http://localhost:8000
DB_CONNECTION=sqlite # database/database.sqlite, already migrated
SESSION_DRIVER=database
QUEUE_CONNECTION=database
CACHE_STORE=database
MAIL_MAILER=log # mail is written to the log in development
SQLite as the default means a new application works with no database server; sessions, the cache and the queue use
database tables, so the only moving part is PHP. Switching to MySQL or PostgreSQL is a change of the DB_* variables
and php artisan migrate. The .env file holds secrets and differs per machine; it is in .gitignore, and only
.env.example is committed.
composer.json requires php: ^8.3, laravel/framework: ^13.17 and laravel/tinker, and for development Pest 4,
Pint (the code formatter), Pail (log tailing), Collision (error output), Mockery and Faker. The skeleton installs Pest
4, not Pest 5, because Pest 5 requires PHP 8.4 and Laravel 13 still supports 8.3. A new application also contains
AGENTS.md and CLAUDE.md with Laravel’s guidelines for AI coding agents.
php artisan about summarises the result:
Environment ..
Application Name .. Laravel
Laravel Version .. 13.34.0
PHP Version .. 8.3.6
Composer Version .. 2.8.12
Environment .. local
Debug Mode .. ENABLED
URL .. localhost:8000
Maintenance Mode .. OFF
Source: Laravel — Artisan Console
The directories and the boot file are explained on Directory Structure and Configuration.
Running it in development
cd bookshelf
npm install && npm run build # once, to build the front-end assets
composer run dev # runs: php artisan dev
composer run dev runs php artisan dev (Laravel 13), which starts every process local development needs in one
terminal: the PHP development server (artisan serve, on http://localhost:8000), a queue worker
(queue:listen --tries=1 --timeout=0), log tailing with Pail (when the pcntl extension is available) and the Vite
development server. Extra processes are registered in a service provider:
<?php
// app/Providers/AppServiceProvider.php, in boot()
use Illuminate\Foundation\DevCommands;
DevCommands::artisan('horizon', 'horizon'); // php artisan horizon instead of queue:listen
DevCommands::node('storybook', 'storybook'); // npm run storybook
DevCommands::register('my-command --flag', 'my-process')->green();
Source: Laravel — The Dev Command and Creating an Application
In Laravel 12, composer run dev ran the same four processes through the concurrently npm package. Herd users
skip artisan serve: Herd serves the application as https://bookshelf.test.
The first loop: route, controller, model, view
Most features follow the same path: a route maps a URL to a controller, the controller uses a model to read or write the database, and returns a view. Artisan generates the files:
$ php artisan make:model Book --migration --factory --controller --resource
INFO Model [app/Models/Book.php] created successfully.
INFO Factory [database/factories/BookFactory.php] created successfully.
INFO Migration [database/migrations/2026_10_05_193247_create_books_table.php] created successfully.
INFO Controller [app/Http/Controllers/BookController.php] created successfully.
Add the columns to the migration and run it:
<?php
// database/migrations/2026_10_05_193247_create_books_table.php (the up() method)
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->unsignedSmallInteger('published_year')->nullable();
$table->timestamps();
});
$ php artisan migrate
INFO Running migrations.
2026_10_05_193247_create_books_table .. 3.11ms DONE
Source: Laravel — Migrations
Declare which attributes may be mass-assigned, register the routes, and fill in two controller methods:
<?php
// app/Models/Book.php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
#[Fillable(['title', 'published_year'])]
class Book extends Model
{
/** @use HasFactory<\Database\Factories\BookFactory> */
use HasFactory;
}
<?php
// routes/web.php
use App\Http\Controllers\BookController;
use Illuminate\Support\Facades\Route;
Route::resource('books', BookController::class)->only(['index', 'show']);
<?php
// app/Http/Controllers/BookController.php
namespace App\Http\Controllers;
use App\Models\Book;
use Illuminate\View\View;
class BookController extends Controller
{
public function index(): View
{
return view('books.index', ['books' => Book::orderBy('title')->get()]);
}
public function show(Book $book): View // route model binding: 404 when the id does not exist
{
return view('books.show', ['book' => $book]);
}
}
Source: Laravel — Mass Assignment, Routing and Resource Controllers
{{-- resources/views/books/index.blade.php --}}
<h1>Books</h1>
<ul>
@forelse ($books as $book)
<li><a href="{{ route('books.show', $book) }}">{{ $book->title }}</a></li>
@empty
<li>No books yet.</li>
@endforelse
</ul>
{{-- resources/views/books/show.blade.php --}}
<h1>{{ $book->title }}</h1>
<p>Published {{ $book->published_year }}</p>
Source: Laravel — Blade Templates
Add a book from the command line with Tinker, then request the pages:
$ php artisan tinker --execute="App\Models\Book::create(['title' => 'Kindred', 'published_year' => 1979]);"
$ php artisan route:list --path=books
GET|HEAD books .. books.index › BookController@index
GET|HEAD books/{book} .. books.show › BookController@show
Showing [2] routes
$ curl localhost:8000/books
<h1>Books</h1>
<ul>
<li><a href="http://localhost:8000/books/1">Kindred</a></li>
</ul>
$ curl localhost:8000/books/1
<h1>Kindred</h1>
<p>Published 1979</p>
$ curl -o /dev/null -w '%{http_code}\n' localhost:8000/books/99
404
Source: Laravel — Tinker and The Route List
Everything the framework-free pages built by hand is here by convention: a front controller and router, route
parameters bound to database rows (with a 404 for unknown IDs), automatic escaping in {{ }}, named routes that
generate URLs, and a migration that describes the schema in code. The pages that follow take each layer in turn,
starting with Request Lifecycle.
Learning resources
-
The official documentation, versioned per release; this section links the 13.x pages throughout.
-
Laravel Learn (
laravel.com/learn), the official step-by-step tutorials, and Laracasts' video courses. -
Laravel Boost, an MCP server and set of guidelines that give AI coding agents version-specific Laravel documentation and tools (
composer require laravel/boost --dev, thenphp artisan boost:install); see AI SDK, MCP and Boost. -
Laravel LSP (
composer global require laravel/lsp), a language server for editors, used by the official VS Code, Sublime Text and Zed extensions; PhpStorm has built-in Laravel support.
Releases and support
Laravel ships one major release a year, in the first quarter. Each major release gets 18 months of bug fixes and 2 years of security fixes. Minor and patch releases come weekly and do not break compatibility. The supported versions on 2026-10-05:
| Version | PHP | Released | Bug fixes until | Security fixes until |
|---|---|---|---|---|
10 |
8.1 to 8.3 |
2023-02-14 |
2024-08-06 |
2025-02-04 (end of life) |
11 |
8.2 to 8.4 |
2024-03-12 |
2025-09-03 |
2026-03-12 (end of life) |
12 |
8.2 to 8.5 |
2025-02-24 |
2026-08-13 |
2027-02-24 (security fixes only) |
13 |
8.3 to 8.5 |
2026-03-17 |
Q3 2027 |
2028-03-17 |
Laravel 14 is expected in the first quarter of 2027 and to require PHP 8.4. Laravel’s first-party libraries (Sanctum, Horizon and the others) support only their latest major version. Upgrading between majors is described on What’s Changed and Upgrading.
Where older books and tutorials are outdated
-
Homestead and Valet (the development environments in Laravel 5.8-era material such as Stauffer ch. 2) are legacy; use Herd, Sail or a local PHP with
php artisan dev. -
composer create-project laravel/laravelfollowed byphp artisan key:generateand a manually created MySQL database is now onelaravel new, with SQLite already migrated. -
php artisan make:auth(Laravel 5.x) is gone; authentication comes from the starter kits (see Authentication). -
Laravel Mix and
npm run watchbecame Vite andnpm run dev(Laravel 9.x);php artisan devruns Vite together with the server and a queue worker. -
The release cadence: Laravel 5.x and 6.x had six-month releases and LTS versions; since Laravel 9 there is one major release a year and no LTS.