Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Building Web Apps with Laravel  Module 1 – Start here: Laravel 13 in 2026

Install PHP, Composer and Laravel 13

Choose an install route for PHP 8.5 and Composer, create a Laravel 13 project, read what each step did, start the dev processes and fix setup errors.

  • Beginner
  • 15 minutes
  • Examples run with PHP 8.5.11, Composer 2.10.3, Laravel 13.34.0 and Python 3.14.8
  • By MySmartCoPilot
Free lesson, Pro answers: 15 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Choose an install route for PHP, Composer and Laravel 13 that fits your system, and name what each route needs
  • Create a project with composer create-project and explain what each part of its output did
  • Compare laravel new with composer create-project, and list the processes that composer run dev starts
  • Check an installation with php artisan about, and fix three common setup errors from their messages

Before you start

What you’ll learn · Before you start

What you will learn

  • Choose an install route for PHP, Composer and Laravel 13 that fits your system, and name what each route needs
  • Create a project with composer create-project and explain what each part of its output did
  • Compare laravel new with composer create-project, and list the processes that composer run dev starts
  • Check an installation with php artisan about, and fix three common setup errors from their messages

Before you start

On this page

One command, composer create-project laravel/laravel pathshala, turns an empty folder into a working Laravel 13 project: 109 Composer packages, a settings file, a secret application key and a SQLite database with nine tables. The same project fails in three predictable ways on a first day, and each failure is one line to read and one command to fix.

This lesson picks an install route, runs create-project and reads its output step by step, compares it with laravel new, checks the result with php artisan about, lists the four processes behind composer run dev and reproduces the three setup errors on purpose. Pathshala, a fictional coaching-centre manager, is the project that the next lessons extend, starting with the project’s folders and configuration.

Four routes lead to PHP, Composer and Laravel 13

Laravel 13 needs PHP 8.3 or newer, and its release notes list PHP 8.3 to 8.5 as supported. The installation guide asks for three tools before the first project: PHP, Composer: PHP's dependency manager. It reads composer.json, downloads the packages a project needs from Packagist and installs them into the vendor folder. and the Laravel installer, plus Node with npm, or Bun, to build the frontend assets. The php track’s install lesson covers the PHP side in more depth. Four routes cover most computers:

  • php.new. One command per system (macOS, Windows PowerShell, Linux) installs PHP, Composer and the Laravel installer together. Running the command again updates all three.
  • Herd. A desktop app for macOS and Windows that bundles PHP and Nginx, with command line tools for php, composer, laravel, node and npm.
  • Your own PHP and Composer. If both are already installed, composer global require laravel/installer adds the installer. A version manager, Homebrew or your Linux packages give you PHP.
  • Sail. Laravel’s Docker setup: a compose.yaml and a sail script that start PHP and its services in containers. It needs Docker.

This track uses the third route, with mise is a tool that installs several versions of a developer tool and runs a command with the one you name. to run PHP 8.5.11 and Composer 2.10.3 by exact version, so every recording here can be repeated with the same versions. The recordings use no containers, so Sail is described but never shown. Answer three questions about your own computer, and the table marks the routes that fit:

Interactive · answer and compare Which route to PHP and Laravel 13 fits your computer? Answer the three questions. The table marks the routes that fit, and gives the reason under each one that does not.
Which system do you develop on?
Is Docker installed and running on your computer?
Must every computer run the same exact PHP release?

Answer the questions above: the table then marks what fits your case and says why the rest does not.

Four routes to a working Laravel 13 setup against four things a setup needs
Route Runs on What you get An exact PHP release What it needs first
php.new command What it is: one command that installs PHP, Composer and the Laravel installer Good macOS, Windows PowerShell and Linux each have a one-line command Good PHP, Composer and the Laravel installer; run the command again to update Mixed the command names a branch such as 8.5, and an update brings the newest release Good a terminal; on Windows, PowerShell opened as administrator
Herd app What it is: a desktop app with PHP and Nginx built in Mixed macOS and Windows only Good PHP, Nginx and command line tools for php, composer, laravel, node and npm Mixed the installer downloads the latest PHP release Good nothing but the installer; on macOS it keeps Nginx running in the background
Your own PHP and Composer What it is: a version manager, Homebrew or your Linux packages Good any system that PHP runs on Mixed you install PHP and Composer yourself, then add the Laravel installer Good mise exec php@8.5.11 runs one named release, as this track does Mixed a version manager, Homebrew or your distribution's packages
Sail What it is: the project runs in Docker containers Mixed macOS, Linux, and Windows through WSL2 Good a compose.yaml and a sail script that start PHP and its services in containers Mixed the images carry their own PHP, and rebuilding them brings newer packages Poor Docker installed and running, and a project to add Sail to
How the answers decide
  • “Which system do you develop on?” Linux: rules out Herd app. Herd is an app for macOS and Windows, so on Linux the other routes take its place.
  • “Which system do you develop on?” Windows: adds a caveat to Sail. Sail runs on Windows through WSL2, a Linux system that runs inside Windows.
  • “Is Docker installed and running on your computer?” No, it does not: rules out Sail. Sail starts its services as Docker containers, so it cannot run without Docker.
  • “Must every computer run the same exact PHP release?” Yes, the same release: adds a caveat to php.new command and Herd app. They install the newest release, so two computers can end on different patch releases.

In short: php.new or Herd for the shortest way to a first project, your own PHP when you must name an exact release, and Sail when a team already works in Docker.

Which PHP versions Laravel 13 supports

Laravel 13 supports PHP 8.3, 8.4 and 8.5, and the skeleton’s composer.json requires php at ^8.3. A computer with PHP 8.2 does not meet that, whatever else is installed, and composer check-platform-reqs is the command that says so.

Checkpoint

Check: Four install routes

  1. Question 1 of 2 A learner develops on Linux and wants a desktop app that bundles PHP and Nginx. Which route from the lesson does not exist for them?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Herd

    The installation guide gives Herd installers for macOS and Windows only. The other three routes all work on Linux.

  2. Question 2 of 2 A team has no Docker on its computers and no wish to add it. Which route can it not use at all?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Sail

    Sail's own documentation calls it a command line interface for Laravel's default Docker development environment, so Docker comes first. The table marks Sail as ruled out when you answer that Docker is not running.

One create-project command builds the whole project

Run it first, then read it. The session below starts in an empty folder and runs the one command, and it is the longest recording of the lesson, because Composer extracts 109 packages:

composer create-project laravel/laravel pathshala Python · create_project_session.py
"""Creates the course's project the way the Laravel docs' own fallback does it: composer create-project, offline."""

from session import run

run("""
composer create-project laravel/laravel pathshala
""", app=False)

Output

$ composer create-project laravel/laravel pathshala
Creating a "laravel/laravel" project at "./pathshala"
Installing laravel/laravel (v13.10.1)
  - Installing laravel/laravel (v13.10.1): Extracting archive
Created project in pathshala
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 109 installs, 0 updates, 0 removals
  - Locking brick/math (1.0.0)
  - Locking carbonphp/carbon-doctrine-types (3.2.1)
  - Locking dflydev/dot-access-data (v3.0.3)
  … and 106 more lines like these
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 109 installs, 0 updates, 0 removals
  - Installing doctrine/inflector (2.1.0): Extracting archive
  - Installing doctrine/lexer (3.0.3): Extracting archive
  - Installing dragonmantank/cron-expression (v3.6.0): Extracting archive
  … and 106 more lines like these
51 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   INFO  Discovering packages.

  laravel/pail .......................................................... DONE
  laravel/pao ........................................................... DONE
  laravel/tinker ........................................................ DONE
  nesbot/carbon ......................................................... DONE
  nunomaduro/collision .................................................. DONE
  nunomaduro/termwind ................................................... DONE

79 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].

No security vulnerability advisories found.
> @php artisan key:generate --ansi

   INFO  Application key set successfully.

> @php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
> @php artisan migrate --graceful --ansi

   INFO  Preparing database.

  Creating migration table .............................................. DONE

   INFO  Running migrations.

  0001_01_01_000000_create_users_table .................................. DONE
  0001_01_01_000001_create_cache_table .................................. DONE
  0001_01_01_000002_create_jobs_table ................................... DONE

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 create_project_session.py

Composer’s manual describes create-project as the equivalent of a git clone followed by composer install. The first package it installs, laravel/laravel (v13.10.1), is the application skeleton: the folders and files of an empty Laravel app. The line that starts with > is a script from the skeleton’s composer.json copying .env.example to .env, the environment file: The .env file in a Laravel project. It holds the values that differ from one computer to the next, such as the database settings, the debug flag and the application key, and stays out of version control. More in “Project structure, configuration and Artisan”. Then Composer works in two phases. Lock file operations: 109 installs is the first: it resolves every package the skeleton needs, development tools included, and Writing lock file saves the exact versions to lock file: composer.lock records the exact version of every package Composer resolved. composer install reads it, so every computer installs the same code.. Package operations: 109 installs is the second: it installs those same versions into the vendor folder.

The recording ran offline from a local copy of the same versions. On your computer Composer fetches them from Packagist: The default package repository for Composer. Composer asks it where to download a package such as laravel/framework., the default package repository, and the output is the same.

After the install, three more scripts finish the setup. Package discovery found six packages that register themselves with Laravel. Application key set successfully is key:generate filling in the application key: The secret stored as APP_KEY in the environment file. Laravel's encrypter uses it, php artisan key:generate creates it, and each environment has its own.. The last block creates the empty SQLite file and runs three migration: A schema change written as a PHP class with an up method that applies it and a down method that undoes it, kept in database/migrations and run in file-name order. More in “Your first CRUD feature with Eloquent”, which build eight tables for users, sessions, the cache and jobs, beside the migrations table that records them. Step through the same run:

Interactive · stage by stage What composer create-project did, in order Step through the eight stages. Each one matches lines of the recorded output above.
What composer create-project did, in order, step 8 of 8. Showing Download the skeleton, Copy .env.example, Resolve and lock (109 packages), Install the packages (109 in vendor), Discover packages (6 packages found), Generate the app key (base64 value, hidden), Create the SQLite file, Run the migrations (3 migrations run). In focus: Run the migrations.Download the skeletonlaravel/laravel 13.10.1Copy .env.examplesettings fileResolve and lock109 packagesInstall the packages109 in vendorDiscover packages6 packages foundGenerate the app keybase64 value, hiddenCreate the SQLite filedatabase.sqliteRun the migrations3 migrations run

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. The skeleton arrives. Composer fetches the application skeleton, version 13.10.1 of laravel/laravel, and extracts it into a new folder called pathshala. It holds the folders you will work in, but no third-party code yet.
  2. .env is copied. A script in the skeleton's composer.json copies .env.example to .env if there is no .env. The settings file now exists, with an empty APP_KEY for the step that fills it.
  3. 109 packages are locked. Composer resolves the skeleton's requirements, framework 13.34.0 among them, and writes every exact version to composer.lock. The output counts 109 installs, development tools included.
  4. The packages are installed. Composer installs the same 109 packages from the lock file into the vendor folder, then builds its autoloader, the map that lets PHP find a class by name.
  5. Packages announce themselves. Laravel runs package discovery. Packages that ship a Laravel service provider, six in this run, are registered without any line of your code. They include Tinker, Pail and Carbon.
  6. The key is generated. php artisan key:generate writes a random value into APP_KEY in .env. Laravel's encrypter needs it, so the step runs once for each new copy of the project.
  7. The database file is created. The default database is SQLite, one file. An empty database/database.sqlite is created, so the first migration has somewhere to write.
  8. Three migrations build tables. php artisan migrate creates its own migrations table and runs the three migrations. They build eight more tables, among them users, sessions, cache and jobs, so the database holds nine. The project is ready to start.

Key idea

create-project is a clone, an install from a lock file and three setup scripts in one command, and the lock file it writes is what lets a teammate repeat the install exactly.

Checkpoint

Check: What create-project builds

  1. One question The output of create-project says "Lock file operations: 109 installs", and later "Package operations: 109 installs". What is the difference?

    Choose one answer.

    Show the answer: One question

    Answer: The first resolves versions and writes composer.lock, and the second installs those versions into vendor

    Composer resolves the requirements into exact versions and writes them to composer.lock. It then installs from that lock file. Because the second phase reads the file, the same install can be repeated on any computer.

laravel new asks the questions create-project skips

laravel new pathshala is a different program: the Laravel installer, put on your computer by php.new, Herd or composer global require laravel/installer. It still builds on the same skeleton, since the installer’s source runs composer create-project laravel/laravel underneath, but it asks questions first and then adjusts the project to your answers. Its source asks, in this order:

Question Choices What create-project gives
Project name any folder name the name you typed in the command
Starter kit? no (default) or yes none
Frontend stack Blade (default), React, Svelte, Vue or Livewire; with a kit, the last four Blade views only
Authentication provider Laravel’s own, or WorkOS (asked with a kit) none
Testing framework Pest (default) or PHPUnit PHPUnit
Laravel Boost? yes or no not installed
Database SQLite, MySQL, MariaDB, PostgreSQL, SQL Server SQLite

A starter kit is a ready-made set of routes, controllers and views for registering and signing in users, and the documentation says plainly that kits are optional. Boost is Laravel’s optional package that gives coding assistants facts about your project. The recordings in this track use create-project, because it needs only Composer and prints no questions, so a recorded session can repeat it. The Pathshala project therefore has the plain defaults: Blade views, PHPUnit and SQLite.

Try laravel new on your own computer

Install the installer, run laravel new pathshala-kit, and answer the questions once with a starter kit and once without. Then compare the two routes/web.php files.

Checkpoint

Check: laravel new and its questions

  1. One question Which of these does laravel new ask about that composer create-project laravel/laravel never asks?

    Choose one answer.

    Show the answer: One question

    Answer: Whether to use a starter kit

    The installer's source asks for the name, a starter kit, the testing framework and Boost, and for a database when none is set. create-project runs the skeleton's scripts and asks nothing.

php artisan about shows the install is sound

Three commands answer “is this setup healthy?” in a few seconds. The version commands name the tools, php artisan about summarises the project, and composer check-platform-reqs compares the PHP on this computer with what the installed packages ask for. The session ends by printing the .env lines behind the driver names, so you can see where each one is set:

Versions, php artisan about and the platform check Python · about_session.py
"""Checks a fresh project: the tool versions, php artisan about, the .env lines behind its drivers, the platform check and the PHP version Composer wrote into vendor."""

from session import run

run(r"""
php -r 'echo "PHP ", PHP_VERSION, "\n";'
composer --version 2>/dev/null | cut -d' ' -f1-3
php artisan --version
php artisan about
grep -E '^(DB_CONNECTION|SESSION_DRIVER|CACHE_STORE|QUEUE_CONNECTION|MAIL_MAILER)=' .env
composer check-platform-reqs
grep 'Your Composer dependencies' vendor/composer/platform_check.php
""", app=True)

Output

$ php -r 'echo "PHP ", PHP_VERSION, "\n";'
PHP 8.5.11
$ composer --version 2>/dev/null | cut -d' ' -f1-3
Composer version 2.10.3
$ php artisan --version
Laravel Framework 13.34.0
$ php artisan about
  Environment ................................................................
  Application Name ................................................... Laravel
  Laravel Version .................................................... 13.34.0
  PHP Version ......................................................... 8.5.11
  Composer Version .................................................... 2.10.3
  Environment .......................................................... local
  Debug Mode ......................................................... ENABLED
  URL ......................................................... localhost:8000
  Maintenance Mode ....................................................... OFF
  Timezone ............................................................... UTC
  Locale .................................................................. en

  Cache ......................................................................
  Config .......................................................... NOT CACHED
  Events .......................................................... NOT CACHED
  Routes .......................................................... NOT CACHED
  Views ........................................................... NOT CACHED

  Drivers ....................................................................
  Broadcasting ........................................................... log
  Cache ............................................................. database
  Database ............................................................ sqlite
  Logs ........................................................ stack / single
  Mail ................................................................... log
  Queue ............................................................. database
  Session ........................................................... database

  Storage ....................................................................
  public/storage .................................................. NOT LINKED
$ grep -E '^(DB_CONNECTION|SESSION_DRIVER|CACHE_STORE|QUEUE_CONNECTION|MAIL_MAILER)=' .env
DB_CONNECTION=sqlite
SESSION_DRIVER=database
QUEUE_CONNECTION=database
CACHE_STORE=database
MAIL_MAILER=log
$ composer check-platform-reqs
Checking platform requirements for packages in the vendor dir
composer-runtime-api 2.2.2      success
ext-ctype            *          success provided by symfony/polyfill-ctype
ext-dom              20031129   success
ext-fileinfo         8.5.11     success
ext-filter           8.5.11     success
ext-hash             8.5.11     success
ext-iconv            8.5.11     success
ext-json             8.5.11     success
ext-libxml           8.5.11     success
ext-mbstring         *          success provided by symfony/polyfill-mbstring
ext-openssl          8.5.11     success
ext-pcre             8.5.11     success
ext-phar             8.5.11     success
ext-session          8.5.11     success
ext-tokenizer        8.5.11     success
ext-xml              8.5.11     success
ext-xmlwriter        8.5.11     success
php                  8.5.11     success
$ grep 'Your Composer dependencies' vendor/composer/platform_check.php
    $issues[] = 'Your Composer dependencies require a PHP version ">= 8.4.1". You are running ' . PHP_VERSION . '.';

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 about_session.py

about has four blocks. Environment says local with debug mode on, because the skeleton’s .env sets APP_ENV=local and APP_DEBUG=true; both change on a live server. Cache says all four caches are NOT CACHED, which is right while you develop. Drivers shows what Laravel will use for each service: SQLite for the database, and the database driver for sessions, cache and queue, each set by one line in .env. Mail goes to the log, so no message leaves your computer. Storage says public/storage is not linked yet.

The platform check prints one line for each requirement, and all 18 lines say success. A line that ends with provided by symfony/polyfill-mbstring means a package supplies a stand-in for the extension, so Composer is satisfied without it. Composer’s manual says this command ignores the config.platform setting and checks the real platform, which makes it the check to run on a server. Laravel 13.34 asks for seven PHP extension: A module that adds functions or classes to PHP, such as mbstring for text or pdo_sqlite for SQLite databases. Laravel needs several of them.: ctype, filter, hash, mbstring, openssl, session and tokenizer.

The last line of the session is a surprise worth reading. Laravel 13 allows PHP 8.3, yet the packages Composer locked on PHP 8.5.11 include Symfony 8.1 components that need PHP 8.4.1, and Composer wrote the highest minimum it found into vendor/composer/platform_check.php. That file runs when the autoloader loads and stops the application with a clear message on an older PHP. Composer chooses package versions that fit the PHP it runs on, so the same command on PHP 8.3 may lock older releases.

Checkpoint

Check: Checking an install

  1. Question 1 of 2 php artisan about shows "Session ... database" on a fresh project. Where is that choice written?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: In the .env file, as SESSION_DRIVER=database

    The about command reads Laravel's configuration, which takes these values from .env. The lesson's grep shows SESSION_DRIVER, CACHE_STORE and QUEUE_CONNECTION all set to database.

  2. Question 2 of 2 composer check-platform-reqs prints "ext-mbstring * success provided by symfony/polyfill-mbstring". What does that tell you?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: A package supplies a stand-in for the extension, so Composer is satisfied even where the extension is missing

    Composer's check treats a package that declares it provides an extension as meeting the requirement. doctor.php asks PHP itself with extension_loaded, so it reports the real extensions.

composer run dev starts four processes in one terminal

The installation guide says that after npm install && npm run build you start everything with composer run dev, and open http://localhost:8000. The command does less than it seems. It runs a script from composer.json, which runs php artisan dev, and that starts the processes. You can list them without starting any, which is how the recording below shows them, because the Vite process needs Node and npm packages that these recordings do not install:

What composer run dev runs, listed without starting it Python · dev_list_session.py
"""Lists the processes composer run dev starts, without starting them."""

from session import run

run(r"""
grep -A 3 '"dev": \[' composer.json
composer run --list
php artisan dev:list
""", app=True)

Output

$ grep -A 3 '"dev": \[' composer.json
        "dev": [
            "Composer\\Config::disableProcessTimeout",
            "@php artisan dev"
        ],
$ composer run --list
scripts:
  setup                     Runs the setup script as defined in composer.json
  dev                       Runs the dev script as defined in composer.json
  test                      Runs the test script as defined in composer.json
  post-autoload-dump
  post-update-cmd
  post-root-package-install
  post-create-project-cmd
  pre-package-uninstall     Runs the pre-package-uninstall script as defined in composer.json
$ php artisan dev:list
  server php artisan serve  Illuminate\Foundation\Providers\ArtisanServicePro…
  queue  php artisan queue:listen --tries=1 --timeout=0  Illuminate\Foundatio…
  logs   php artisan pail --timeout=0  Illuminate\Foundation\Providers\Artisa…
  vite   npm run dev  Illuminate\Foundation\Providers\ArtisanServiceProvider@…

                                                      Showing [4] dev commands

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 dev_list_session.py

The first lines show the dev script: it switches off Composer’s process time limit and then calls @php artisan dev. The table lists four named processes: server (php artisan serve), queue (a worker that listens for jobs), logs (Pail, which prints log lines as they are written) and vite (npm run dev, which rebuilds CSS and JavaScript when you save). The table is cut at 80 columns, so the last column of each row shows where the process was registered. Walk through the command once:

Interactive · step by step One command, four processes Step through composer run dev. Each step starts or explains one part of the chain.
One command, four processes, step 7 of 7. Showing composer run dev, php artisan dev, server (localhost:8000), queue (waiting for jobs), logs (Pail), vite (needs Node and npm). In focus: php artisan dev.composer run devphp artisan devserverlocalhost:8000queuewaiting for jobslogsPailviteneeds Node and npm

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. You type one command. composer run dev runs the dev script in composer.json. The script turns off Composer's time limit, so the long-running processes are not cut off, and then runs php artisan dev.
  2. Artisan takes over. php artisan dev starts every process needed for local work in one terminal window. It needs Node 22.13 or later, because it manages the processes with an npm package.
  3. The web server starts. The server process runs php artisan serve, and the page is then at http://localhost:8000. This process is all a learner needs to see the notices page of the next lessons.
  4. A queue worker listens. The queue process runs queue:listen with one try for each job and no time limit. The default queue stores jobs in the database, so this worker is waiting on the jobs table.
  5. Logs are tailed. The logs process runs Pail, which prints the application's log lines as they are written, so errors show up in the same window as the server.
  6. Vite watches the assets. The vite process runs npm run dev, which rebuilds CSS and JavaScript when you save. It needs Node and installed npm packages, so it cannot run in this lesson's recordings.
  7. A crash restarts a process. If a process crashes, Laravel restarts it after a short delay, up to five times. One that dies within a second of starting is not restarted, because it most likely never started.

The dev command needs Node 22.13 or later and, on Windows, falls back to the concurrently npm package without the tabbed screen. Vite itself needs Node 20.19 or 22.12 and later. To run only some processes, DevCommands::only('server', 'vite') in a service provider filters them, and php artisan dev --no-restart turns off the automatic restarts.

Two terminals do the same job

Without Node, php artisan serve alone serves the pages for the first lessons. Add the queue worker and the Vite process when a lesson needs them.

Checkpoint

Check: The dev processes

  1. Question 1 of 2 Which of these are processes that php artisan dev starts by default? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 1 of 2

    Answer:

    • logs, which runs Pail
    • queue, which runs queue:listen
    • vite, which runs npm run dev
    • server, which runs php artisan serve

    php artisan dev:list shows four processes: server, queue, logs and vite. There are four rows in the table and none for mail.

  2. Question 2 of 2 A learner on Node 18 runs composer run dev. Which statement fits the documentation?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The dev command needs Node 22.13 or later, so Node 18 is too old for it

    The Artisan guide says the dev command requires Node 22.13 or later, and that Windows falls back to the concurrently package. Vite adds its own minimum of Node 20.19 or 22.12.

Three setup errors, each with a one-line fix

Most first-day failures are one of three messages. Reproduce the first two in a recorded session: running artisan in the wrong folder, and starting from a project that has no application key, as every clone from Git does.

Two setup errors on purpose, and their fixes Python · errors_session.py
"""Two setup errors that artisan reports itself: run outside the project, and a missing application key."""

from session import run

run("""
# Error 1: artisan, one folder above the project
cd ..
!php artisan about
cd pathshala
php artisan --version
# Error 2: a project copied from Git has no .env, only .env.example
cp .env.example .env
grep -c '^APP_KEY=$' .env
!php artisan tinker --execute="echo encrypt('hello');"
php artisan key:generate
grep -c '^APP_KEY=base64:' .env
php artisan tinker --execute="echo decrypt(encrypt('hello'));"
""", app=True)

Output

# Error 1: artisan, one folder above the project
$ cd ..
$ php artisan about
Could not open input file: artisan
[exit status 1]
$ cd pathshala
$ php artisan --version
Laravel Framework 13.34.0
# Error 2: a project copied from Git has no .env, only .env.example
$ cp .env.example .env
$ grep -c '^APP_KEY=$' .env
1
$ php artisan tinker --execute="echo encrypt('hello');"
   Illuminate\Encryption\MissingAppKeyException  No application encryption key has been specified.
[exit status 1]
$ php artisan key:generate
   INFO  Application key set successfully.
$ grep -c '^APP_KEY=base64:' .env
1
$ php artisan tinker --execute="echo decrypt(encrypt('hello'));"
hello

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 errors_session.py

Could not open input file: artisan means PHP looked for a file called artisan in the current folder and found none. artisan is a file at the project root, so the fix is cd into the folder that holds artisan and composer.json. The second error appears because the installation guide says .env should not be committed to source control, so a clone has only .env.example, whose APP_KEY= is empty. Laravel’s encryption guide says the encrypter needs that key and tells you to create it with php artisan key:generate. After the fix, encrypt and decrypt round-trip the word hello.

Keep the key out of Git, tickets and chat

The key protects everything Laravel encrypts. Each environment gets its own, made by key:generate, and a real one is never pasted into a repository, a ticket or a message.

The third error shows up in a browser. A page that asks Vite for its files before they are built answers with a 500. This project has no public/build/manifest.json, because npm run build has not run. The session serves two pages from one small overlay, one that asks for the files and one that checks first, the way the skeleton’s own welcome page does:

Two pages that use @vite, one unguarded and one guarded

routes/web.php · vite-page/routes/web.php

<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

// A page that asks Vite for its CSS and JavaScript with no guard.
Route::get('/vite-demo', function () {
    return view('vite-demo');
});

// The same page with the guard that the welcome view uses.
Route::get('/vite-guarded', function () {
    return view('vite-guarded');
});

vite-page/resources/views/vite-demo.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Pathshala</title>
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body>
        <h1>Pathshala notices</h1>
    </body>
</html>

vite-page/resources/views/vite-guarded.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Pathshala</title>
        @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot')))
            @vite(['resources/css/app.css', 'resources/js/app.js'])
        @endif
    </head>
    <body>
        <h1>Pathshala notices</h1>
    </body>
</html>
A page that uses @vite before npm run build Python · vite_session.py
"""A page that asks for Vite's files before they exist: the 500, its cause and two ways out."""

from session import serve

serve(port=8213, requests=r"""
curl -s -o /dev/null -w "status %{http_code}\n" http://127.0.0.1:8213/vite-demo
curl -s -H "Accept: application/json" http://127.0.0.1:8213/vite-demo | grep '"message"'
curl -s -o /dev/null -w "status %{http_code}\n" http://127.0.0.1:8213/vite-guarded
""", overlay=("vite-page",))

Output

# Terminal 1: start the server
$ php artisan serve --host=127.0.0.1 --port=8213 --no-reload
# Terminal 2: send requests
$ curl -s -o /dev/null -w "status %{http_code}\n" http://127.0.0.1:8213/vite-demo
status 500
$ curl -s -H "Accept: application/json" http://127.0.0.1:8213/vite-demo | grep '"message"'
    "message": "Vite manifest not found at: public/build/manifest.json (View: resources/views/vite-demo.blade.php)",
$ curl -s -o /dev/null -w "status %{http_code}\n" http://127.0.0.1:8213/vite-guarded
status 200
# Terminal 1 showed this, then Ctrl+C stopped the server:
   INFO  Server running on [http://127.0.0.1:8213].

  Press Ctrl+C to stop the server

  … /vite-demo ........................................ ~ …
  … /vite-demo ........................................ ~ …
  … /vite-guarded ..................................... ~ …

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 vite_session.py

The unguarded page answers status 500 (the HTTP status codes tool lists what each code means), and asking for JSON shows the message: Vite manifest not found, with the path it looked in. The guarded page answers status 200. The real fix is to build the assets with npm install && npm run build, or keep npm run dev running, which the vite process of composer run dev does. The guard is a stop-gap for a page that must work before any build. Other first-day failures have the same shape, a message that names the missing piece: a PHP older than 8.3, a missing extension, and a Node too old for Vite.

Checkpoint

Check: Three setup errors

  1. Question 1 of 2 php artisan about prints "Could not open input file: artisan". What is wrong?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The terminal is in a folder that has no artisan file, so it is not the project root

    The message comes from PHP's command line, before any Laravel code runs. The fix is to cd into the folder that holds artisan and composer.json.

  2. Question 2 of 2 A page that uses @vite answers 500 with "Vite manifest not found" on a project where npm run build has never run. Which fix addresses the cause?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Build the assets with npm install && npm run build, or keep npm run dev running

    @vite reads public/build/manifest.json, which npm run build writes. The guard in the skeleton's welcome view skips @vite until the manifest or the hot file exists.

A setup report names the check that failed

Messages arrive one at a time, in the order you trip over them. A report lists every check at once. doctor.php is a small PHP script of this lesson: it checks the PHP version, eight extensions and five things about the project, and prints the result as JSON. It reads .env only to see whether APP_KEY starts with base64:, and it never prints the key. The script follows, then a recorded session that runs it twice:

doctor.php PHP · doctor-tool/doctor.php
<?php

// A setup check for a Laravel 13 project. Run `php doctor.php` inside the project,
// or `php doctor.php path/to/project`. It prints a JSON report and changes nothing.

$folder = rtrim($argv[1] ?? '.', '/\\');

// What laravel/framework 13.34 requires, plus the driver the default .env uses (SQLite).
$extensions = ['ctype', 'filter', 'hash', 'mbstring', 'openssl', 'session', 'tokenizer', 'pdo_sqlite'];

// Read .env as plain text: the key is only checked, never printed.
$values = [];
if (is_file($folder.'/.env')) {
    foreach (file($folder.'/.env', FILE_IGNORE_NEW_LINES) as $line) {
        if (preg_match('/^([A-Z_]+)=(.*)$/', $line, $match)) {
            $values[$match[1]] = $match[2];
        }
    }
}

$checks = ['php-version' => PHP_VERSION_ID >= 80300 ? 'ok' : 'fail'];
foreach ($extensions as $name) {
    $checks['ext-'.$name] = extension_loaded($name) ? 'ok' : 'fail';
}
$checks['artisan'] = is_file($folder.'/artisan') ? 'ok' : 'fail';
$checks['vendor'] = is_file($folder.'/vendor/autoload.php') ? 'ok' : 'fail';
$checks['env-file'] = is_file($folder.'/.env') ? 'ok' : 'fail';
$checks['app-key'] = str_starts_with($values['APP_KEY'] ?? '', 'base64:') ? 'ok' : 'fail';

$usesSqlite = ($values['DB_CONNECTION'] ?? 'sqlite') === 'sqlite';
$checks['sqlite-file'] = ! $usesSqlite || is_file($folder.'/database/database.sqlite') ? 'ok' : 'fail';

$failed = count(array_filter($checks, fn (string $result): bool => $result !== 'ok'));

echo json_encode(
    ['php' => PHP_VERSION, 'failed' => $failed, 'checks' => $checks],
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
), "\n";

exit($failed === 0 ? 0 : 1);
doctor.php inside the project, and on a folder that is not one Python · doctor_session.py
"""Runs the setup check inside the project, then on a folder that is not a project."""

from session import run

run("""
php doctor.php
cd ..
!php pathshala/doctor.php .
""", app=True, overlay=("doctor-tool",))

Output

$ php doctor.php
{
    "php": "8.5.11",
    "failed": 0,
    "checks": {
        "php-version": "ok",
        "ext-ctype": "ok",
        "ext-filter": "ok",
        "ext-hash": "ok",
        "ext-mbstring": "ok",
        "ext-openssl": "ok",
        "ext-session": "ok",
        "ext-tokenizer": "ok",
        "ext-pdo_sqlite": "ok",
        "artisan": "ok",
        "vendor": "ok",
        "env-file": "ok",
        "app-key": "ok",
        "sqlite-file": "ok"
    }
}
$ cd ..
$ php pathshala/doctor.php .
{
    "php": "8.5.11",
    "failed": 5,
    "checks": {
        "php-version": "ok",
        "ext-ctype": "ok",
        "ext-filter": "ok",
        "ext-hash": "ok",
        "ext-mbstring": "ok",
        "ext-openssl": "ok",
        "ext-session": "ok",
        "ext-tokenizer": "ok",
        "ext-pdo_sqlite": "ok",
        "artisan": "fail",
        "vendor": "fail",
        "env-file": "fail",
        "app-key": "fail",
        "sqlite-file": "fail"
    }
}
[exit status 1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 doctor_session.py

Inside the project every check says ok and the exit status is 0. Pointed at the parent folder, five checks fail, failed is 5 and the exit status is 1, so a shell script or a CI step can stop on it. Each failing name points at one fix: artisan means the wrong folder, vendor means composer install has not run, env-file and app-key mean the steps of the second error above. The second program reads three reports of the same shape and explains each failed check. Copy it, change one ok to fail in a report, and run php explain_report.php to see the advice for that check:

Explaining the failed checks of three reports PHP · explain_report.php
<?php

// Reads setup reports in the shape doctor.php prints and explains every check that failed.

$advice = [
    'php-version' => ['Laravel 13 needs PHP 8.3 or newer.', 'install PHP 8.3, 8.4 or 8.5, then open a new terminal'],
    'ext-mbstring' => ['PHP has no mbstring extension, which the framework needs for text.', 'enable it in php.ini or install the extension package'],
    'ext-pdo_sqlite' => ['The default database is SQLite and PHP cannot open it.', 'enable pdo_sqlite, or pick another database in .env'],
    'artisan' => ['This folder is not a Laravel project: there is no artisan file.', 'cd into the project folder'],
    'vendor' => ['The Composer packages are not installed.', 'composer install'],
    'env-file' => ['There is no .env file, so no settings.', 'copy .env.example to .env'],
    'app-key' => ['APP_KEY is empty, and encryption needs it.', 'php artisan key:generate'],
    'sqlite-file' => ['The SQLite database file does not exist.', 'create database/database.sqlite, then php artisan migrate'],
];

$reports = [
    'A project just made by create-project' => '{"php":"8.5.11","failed":0,"checks":{"php-version":"ok","artisan":"ok","vendor":"ok","env-file":"ok","app-key":"ok","sqlite-file":"ok"}}',
    'A clone from Git, before any setup' => '{"php":"8.5.11","failed":4,"checks":{"php-version":"ok","artisan":"ok","vendor":"fail","env-file":"fail","app-key":"fail","sqlite-file":"fail"}}',
    'A laptop with an old PHP' => '{"php":"8.2.30","failed":2,"checks":{"php-version":"fail","ext-mbstring":"fail","artisan":"ok","vendor":"ok","env-file":"ok","app-key":"ok","sqlite-file":"ok"}}',
];

foreach ($reports as $title => $json) {
    $report = json_decode($json, true, flags: JSON_THROW_ON_ERROR);
    echo $title, ' (PHP ', $report['php'], ', ', $report['failed'], " failed)\n";

    foreach ($report['checks'] as $name => $result) {
        if ($result === 'ok') {
            continue;
        }
        [$why, $fix] = $advice[$name];
        printf("  %-14s %s\n", $name, $why);
        echo '                 fix: ', $fix, "\n";
    }

    if ($report['failed'] === 0) {
        echo "  every check passed\n";
    }
}

Output

A project just made by create-project (PHP 8.5.11, 0 failed)
  every check passed
A clone from Git, before any setup (PHP 8.5.11, 4 failed)
  vendor         The Composer packages are not installed.
                 fix: composer install
  env-file       There is no .env file, so no settings.
                 fix: copy .env.example to .env
  app-key        APP_KEY is empty, and encryption needs it.
                 fix: php artisan key:generate
  sqlite-file    The SQLite database file does not exist.
                 fix: create database/database.sqlite, then php artisan migrate
A laptop with an old PHP (PHP 8.2.30, 2 failed)
  php-version    Laravel 13 needs PHP 8.3 or newer.
                 fix: install PHP 8.3, 8.4 or 8.5, then open a new terminal
  ext-mbstring   PHP has no mbstring extension, which the framework needs for text.
                 fix: enable it in php.ini or install the extension package

Recorded with PHP 8.5.11 (cli) (NTS) on macOS 26 arm64. To run it yourself: php explain_report.php

Checkpoint

Check: A setup report

  1. Question 1 of 2 This is the checks part of a report from doctor.php. Which command repairs the failures it shows?

    Read the code, then choose one answer.

    "checks": {
        "php-version": "ok",
        "artisan": "ok",
        "vendor": "fail",
        "env-file": "ok",
        "app-key": "ok",
        "sqlite-file": "ok"
    }
    Show the answer: Question 1 of 2

    Answer: composer install

    Only one check fails, and the vendor check looks for vendor/autoload.php. composer install reads composer.lock and creates that folder.

  2. Question 2 of 2 doctor.php exits with status 1 when any check fails. Why is that useful?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: A script or CI step can stop on the status without reading the JSON

    The recorded run on a folder that is not a project ended with the line exit status 1. A zero status means every check passed, which is what a build step needs to decide.

Practise: from an empty folder to a checked project

The questions below follow the lesson from the install routes to the report, starting with the idea you have shown least. Each answer says why it is right or what it misses.

Practice that adapts to you

Practise this lesson

14 questions about 7 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 14 Which route does the lesson say uses mise, so that PHP 8.5.11 and Composer 2.10.3 run by exact version?

    Choose one answer.

    Show the answer: Question 1 of 14

    Answer: Your own PHP and Composer

    The lesson uses the third route so that every recording can be repeated. The table marks php.new and Herd with a caveat when every computer must run the same exact release.

  2. Question 2 of 14 A team of three has two Windows laptops and one Mac, all without Docker. Every computer must run the same PHP release. Which route fits best?

    Choose one answer.

    Show the answer: Question 2 of 14

    Answer: Your own PHP and Composer, with a version manager that names the release

    Two conditions decide it. No Docker rules out Sail, and an exact release leaves caveats on php.new and Herd, so a route where you name the version is the one that fits.

  3. Question 3 of 14 Which file records the exact versions of the 109 packages that create-project installed?

    Choose one answer.

    Show the answer: Question 3 of 14

    Answer: composer.lock

    composer.lock holds exact versions, and Composer's manual says to commit it for an application, so everyone installs the same code.

  4. Question 4 of 14 In the output of create-project, which step runs after package discovery and before the migrations?

    Choose one answer.

    Show the answer: Question 4 of 14

    Answer: Generating the application key, then creating the SQLite file

    The recorded order is the skeleton, the .env copy, the lock file, the install, discovery, the key, the SQLite file and the migrations. The migrations come last because they need the database file.

  5. Question 5 of 14 A learner runs composer create-project laravel/laravel and then looks for Pest. What does the project have?

    Choose one answer.

    Show the answer: Question 5 of 14

    Answer: PHPUnit, with no Pest installed

    The installer asks for the testing framework and offers Pest as the default, while the plain skeleton installs PHPUnit. This project therefore uses PHPUnit.

  6. Question 6 of 14 A learner wants sign-in pages generated for a new project. Which choice gets them, and what do the docs say about it?

    Choose one answer.

    Show the answer: Question 6 of 14

    Answer: laravel new with a starter kit, which the docs call optional

    The starter kits page says kits give a head start with authentication and are not required. The installer is where you choose one.

  7. Question 7 of 14 php artisan about shows "Debug Mode ... ENABLED" on the new project. Which setting does that come from?

    Choose one answer.

    Show the answer: Question 7 of 14

    Answer: APP_DEBUG=true in .env

    Debug mode is an application setting read from the environment file. A live server sets it to false.

  8. Question 8 of 14 Laravel 13.34 requires seven PHP extensions, and doctor.php adds pdo_sqlite for the default database. How many extension checks does doctor.php run?

    Type a number.

    Show the answer: Question 8 of 14

    Answer: 8 checks

    Seven required extensions plus pdo_sqlite make eight extension checks. The report in the lesson lists them as ext-ctype, ext-filter, ext-hash, ext-mbstring, ext-openssl, ext-session, ext-tokenizer and ext-pdo_sqlite.

  9. Question 9 of 14 On Windows, composer run dev works but the screen has no tabs for the processes. What does the Artisan guide say?

    Choose one answer.

    Show the answer: Question 9 of 14

    Answer: On Windows the command falls back to the concurrently npm package, without the tabbed screen

    The documentation says the tabbed interface is not available on Windows, where the dev command uses concurrently instead.

  10. Question 10 of 14 The queue process of php artisan dev stays idle during the first lessons. Why does it not fail?

    Choose one answer.

    Show the answer: Question 10 of 14

    Answer: It listens for rows in the jobs table, which the default database queue uses, and none are added yet

    about shows Queue as database, so the worker polls the jobs table and has nothing to do until a job is queued.

  11. Question 11 of 14 A teammate clones the project, runs composer install and starts the app, then sees "No application encryption key has been specified". Which pair of steps fixes it?

    Choose one answer.

    Show the answer: Question 11 of 14

    Answer: Copy .env.example to .env, then run php artisan key:generate

    The key is made on each computer by key:generate, which writes it to .env. The lesson's recording shows the error before the command and a round trip through encrypt and decrypt after it.

  12. Question 12 of 14 A new teammate asks you to send the key from your .env so that the same values work on both computers. What is the better answer?

    Choose one answer.

    Show the answer: Question 12 of 14

    Answer: Send nothing; the teammate runs key:generate, because a key is made for each environment and never shared in a message

    A key made for each environment keeps secrets out of repositories and messages. The documentation's example key is public, so it protects nothing.

  13. Question 13 of 14 doctor.php is run on a folder that is not a Laravel project. Which check fails along with vendor, env-file, app-key and sqlite-file?

    Choose one answer.

    Show the answer: Question 13 of 14

    Answer: artisan

    The recorded run on the parent folder reports failed 5: artisan, vendor, env-file, app-key and sqlite-file. The PHP checks stay ok because they describe the computer, not the folder.

  14. Question 14 of 14 In explain_report.php, the third report has "php-version" and "ext-mbstring" failing while every project check is ok. What does that suggest?

    Choose one answer.

    Show the answer: Question 14 of 14

    Answer: The project is fine and the computer's PHP needs to change, to 8.3 or newer with mbstring enabled

    The failing names tell which side to fix. When only the PHP checks fail, reinstall or reconfigure PHP, and leave the project alone.

Interview questions

Warm-up (fresher): what does composer.lock record, and should an application commit it?

The file records the exact version of every package that Composer resolved from composer.json, including the packages those packages need. composer install reads it and installs exactly those versions, so a teammate, the build server and the production server all get the same code. composer update ignores it, resolves the packages again within the limits of composer.json and rewrites the file. Composer’s manual tells you to commit the lock file for an application, and the create-project run in this lesson wrote one for 109 packages. A library that other projects depend on is the exception, because the projects that use it resolve their own versions.

Warm-up (fresher): how does composer create-project laravel/laravel differ from laravel new?

Both start from the same skeleton package, laravel/laravel. composer create-project downloads it and runs the scripts in its composer.json: copy .env, install the packages, generate the key, create the SQLite file and migrate. It asks nothing and needs only Composer. laravel new is the Laravel installer, a separate program. It asks about the project name, a starter kit, the testing framework and the database first, then builds a project that matches the answers. Use create-project for the plain defaults or a script that cannot answer questions, and laravel new when you want a starter kit or Pest.

Two longer questions from this lesson start where the warm-ups stop:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Mid to senior

    Two branches each added a Composer package to a Laravel app. Merging them conflicts in composer.lock, and a teammate keeps the file from one branch and commits. The build server's composer install then stops with a message that a required package is not in the lock file. What happened, and how do you resolve such a conflict?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    composer.json requires php ^8.3. Developers run PHP 8.5 and production runs 8.3. A developer uses array_find, added in PHP 8.4. Composer installs cleanly on the server, yet a page there fails with a call to an undefined function. Why did nothing warn you, and how do you catch this before deploying?

    Model answer, Pro. First step and follow-ups

Flashcards · 7 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. Which routes lead to PHP, Composer and Laravel 13 on a new machine?

    php.new, Laravel Herd, your own PHP with Composer, or Sail in Docker. Laravel 13 needs PHP 8.3 or newer; the track itself runs exact versions through mise so its recordings can be repeated.

  2. What does composer create-project laravel/laravel do in one command?

    It clones the skeleton, installs the packages from the lock file and runs three setup scripts. The result has 109 packages, a .env file, an application key and a SQLite database with nine tables.

  3. How does laravel new differ from composer create-project?

    laravel new asks about a starter kit, the testing framework and the database before it builds the project. create-project asks nothing and keeps the plain defaults.

  4. Which two commands show in seconds whether a new install is sound?

    php artisan about summarises the project: its versions, drivers and settings. composer check-platform-reqs compares the PHP on this computer, with its extensions, against what the installed packages ask for, so a too-old PHP or a missing extension shows at once.

  5. What starts when you run composer run dev in a new Laravel 13 project?

    It calls php artisan dev, which starts four processes in one terminal: the development server, a queue worker, Pail for the log and Vite for the front-end assets.

  6. What do the three most common first-day setup errors mean?

    Could not open input file: artisan means the command ran outside the project folder; an empty APP_KEY in a fresh clone needs php artisan key:generate; Vite manifest not found means the assets were never built, so run npm run build (or npm run dev).

  7. What does composer.lock record, and should an application commit it?

    The exact version of every package Composer resolved, dependencies of dependencies included. composer install reads it, so every computer gets the same code, while composer update resolves again and rewrites it. An application commits it.

Key takeaways

  • Laravel 13 needs PHP 8.3 or newer, and php.new, Herd, your own PHP with Composer, or Sail each get you there; this track uses mise to run exact versions, so recordings can be repeated.
  • composer create-project laravel/laravel is a clone, an install from a lock file and three setup scripts, and it leaves 109 packages, a .env, an application key and a SQLite database with nine tables.
  • laravel new asks about a starter kit, the testing framework and the database before it builds, while create-project asks nothing and keeps the plain defaults.
  • php artisan about and composer check-platform-reqs show the versions, drivers and extensions of a project in seconds, and composer run dev starts a server, a queue worker, Pail and Vite through php artisan dev.
  • The three first-day errors say what is missing: artisan run outside the project, an empty APP_KEY in a fresh clone, and Vite manifest not found before npm run build.

Terms in this lesson

application key
The secret stored as APP_KEY in the environment file. Laravel's encrypter uses it, php artisan key:generate creates it, and each environment has its own.
Composer
PHP's dependency manager. It reads composer.json, downloads the packages a project needs from Packagist and installs them into the vendor folder.
lock file
composer.lock records the exact version of every package Composer resolved. composer install reads it, so every computer installs the same code.
Packagist
The default package repository for Composer. Composer asks it where to download a package such as laravel/framework.
PHP extension
A module that adds functions or classes to PHP, such as mbstring for text or pdo_sqlite for SQLite databases. Laravel needs several of them.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.