Skip to main content

βš™οΈ Setting Up a Laravel Application

A clean install is the foundation everything else rests on. In this lesson you will create a Laravel 11 project three different ways, learn what each directory is for, configure the environment safely, run your first migration, and meet Artisan β€” the command-line assistant you will use every single day.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • List the prerequisites for Laravel 11 and create a project with Composer, the installer, or Sail
  • Navigate the Laravel directory structure and explain what each top-level folder holds
  • Configure your app through the .env file and generate the application key
  • Connect a database and run migrations to build your schema
  • Use core Artisan commands and start the development server

Estimated Time: 35–45 minutes  β€’  Difficulty: Beginner–Intermediate

Hands-on: Spin up a fresh Laravel 11 app, wire it to SQLite, migrate, and load the welcome page.

In This Lesson

Introduction & Prerequisites

Setting up a Laravel app is like prepping a kitchen before an elaborate meal β€” the time you invest up front pays dividends every time you cook. Whether you are building a blog or an enterprise platform, the setup follows the same repeatable pattern.

Before installing Laravel 11, make sure your machine has:

  • PHP 8.2 or higher β€” Laravel 11 requires it (8.3 is recommended).
  • Composer β€” PHP's dependency manager, used to pull in Laravel and its packages.
  • A database β€” MySQL, PostgreSQL, SQLite, or SQL Server. SQLite needs zero setup, so it is perfect for learning.
  • Node.js & npm β€” for compiling front-end assets with Vite.
  • Required PHP extensions β€” Ctype, cURL, DOM, Fileinfo, Filter, Hash, Mbstring, OpenSSL, PCRE, PDO, Session, Tokenizer, and XML (all standard in a normal PHP build).
flowchart LR A[PHP 8.2+] --> F((Laravel 11)) B[Composer] --> F C[Database] --> F D[Node.js + npm] --> F E[PHP extensions] --> F

πŸ’‘ Not sure what you have?

Run php -v, composer -V, and node -v in a terminal. If PHP reports 8.2 or higher and Composer is present, you are ready to go.

Three Ways to Install

There is more than one road to a new project. Pick the one that matches how often you start Laravel apps and whether you want Docker.

Method 1 β€” Composer create-project

The most direct route. This works anywhere Composer runs and needs nothing installed globally.

composer create-project laravel/laravel example-app
cd example-app
php artisan serve

Think of it as buying a flat-pack furniture kit: every standard piece arrives in the expected place.

Method 2 β€” The Laravel installer

If you spin up Laravel projects often, install the global installer once and use the shorter laravel new command. Modern versions can even scaffold a starter kit, testing framework, and database interactively.

# Install the installer globally (one time)
composer global require laravel/installer

# Create a new project
laravel new example-app

Like a template cutter in a workshop β€” precise and consistent every time.

Method 3 β€” Docker with Laravel Sail

Sail gives you a full Docker environment (PHP, MySQL, Redis, and more) with zero local PHP required. Ideal for keeping every teammate's setup identical.

# Scaffold a new app with a Docker environment
curl -s "https://laravel.build/example-app" | bash

cd example-app

# Bring the containers up
./vendor/bin/sail up

Sail is the pre-calibrated workshop: every tool is already set up so you can focus on building, not configuring.

⚠️ One project, one method

Don't mix approaches inside a single project. Composer and the installer produce the same result β€” Sail simply adds a Docker layer on top. Choose based on whether you want to run PHP locally or in containers.

The Directory Structure

A fresh install is well organized. Knowing the floor plan lets you navigate without hunting. Laravel 11's skeleton is deliberately slimmer than older versions β€” fewer files, clearer defaults.

graph TD A[Project Root] --> B["app/"] A --> C["bootstrap/"] A --> D["config/"] A --> E["database/"] A --> F["public/"] A --> G["resources/"] A --> H["routes/"] A --> I["storage/"] A --> J["tests/"] A --> K["vendor/"] B --> B1["Http/Controllers/"] B --> B2["Models/"] B --> B3["Providers/"] H --> H1["web.php"] H --> H2["console.php"] G --> G1["views/"] G --> G2["css/ & js/"]
DirectoryWhat lives thereAnalogy
app/Your application's core code β€” models, controllers, providersThe workshop floor
bootstrap/app.php (app definition) and the framework cacheThe ignition switch
config/Configuration files that read from .envThe control panel
database/Migrations, seeders, and factoriesBlueprints for your data
public/The single public entry point index.php and built assetsThe front door
resources/Blade views plus raw CSS/JS sourceRaw materials & templates
routes/Route definitions (web.php, console.php)The roadmap
storage/Logs, compiled views, file uploads, cachesThe filing cabinet
tests/Automated tests (Pest or PHPUnit)Quality control
vendor/Composer dependencies (never edited by hand)The supply warehouse

πŸ“– Laravel 11 note

You will not find routes/api.php or routes/channels.php in a fresh 11 app. Add API routing with php artisan install:api and broadcasting with php artisan install:broadcasting. Similarly, config/ ships lean β€” publish any config file you need to customize with php artisan config:publish.

Environment & the .env File

Laravel keeps environment-specific settings β€” database credentials, API keys, debug flags β€” in a .env file at the project root. The same codebase can then run in local, staging, and production simply by swapping this file. Config files in config/ read these values via the env() helper.

# .env (excerpt)
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:GENERATED_KEY_HERE
APP_DEBUG=true
APP_URL=http://localhost

# SQLite β€” the easiest database to start with
DB_CONNECTION=sqlite

# Or MySQL:
# DB_CONNECTION=mysql
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=example_app
# DB_USERNAME=root
# DB_PASSWORD=secret

⚠️ Never commit your .env

.env holds secrets and is git-ignored by default. Commit .env.example instead β€” a placeholder version that documents which variables are needed without real values. New teammates copy it to .env and fill in their own.

The application key

Every Laravel app needs an APP_KEY β€” a random 32-byte string used to encrypt sessions and cookies. The installers generate it for you, but if you clone a project (which won't include the git-ignored .env), generate one:

php artisan key:generate

Without this key, encrypted data cannot be secured β€” treat it like the master key to your building.

πŸ’‘ Analogy: The .env file is a theatre's lighting board. The play (your code) is identical from venue to venue; only the board's settings change to suit each stage.

Database & Migrations

Once your connection is set in .env, you define your schema with migrations β€” versioned PHP files that describe tables. Migrations live in your repository, so your database structure travels with your code and every teammate gets the same schema.

If you chose SQLite, create the empty database file first, then migrate:

# SQLite only: create the database file
touch database/database.sqlite

# Create a migration
php artisan make:migration create_products_table

# Apply all pending migrations
php artisan migrate

# Roll back the most recent batch
php artisan migrate:rollback

# Wipe and re-run everything (great while developing)
php artisan migrate:fresh

A migration has two halves: up() builds the change, down() reverses it.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description')->nullable();
            $table->integer('price_cents');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

βœ… Why migrations beat editing the database by hand

  • Version control β€” schema changes are reviewed and tracked like any other code.
  • Team consistency β€” everyone runs the same migrations and gets identical tables.
  • Repeatable deploys β€” php artisan migrate applies pending changes automatically in production.
  • Reversible β€” a bad change can be rolled back rather than manually undone.

The Artisan CLI

Artisan is Laravel's command-line assistant. It scaffolds files, runs migrations, clears caches, and hosts your dev server β€” the Swiss Army knife you will reach for constantly.

# See every available command
php artisan list

# Help for one command
php artisan help migrate

# Scaffold common pieces
php artisan make:controller ProductController
php artisan make:model Product -m      # model + its migration
php artisan make:migration create_orders_table

# Maintenance
php artisan config:clear
php artisan route:list                  # show every registered route
graph LR A[Artisan] --> B[make:controller] A --> C["make:model -m"] A --> D[make:migration] A --> E[migrate] A --> F[route:list] A --> G[serve] A --> H[make:command]

The make:* commands are the most-used: they generate correctly-named, correctly-placed files so you never start from a blank page. Using Artisan is like having a skilled assistant handle the boilerplate while you focus on the logic.

πŸ’‘ Build your own command

Run php artisan make:command GreetingCommand to scaffold a custom command. In Laravel 11 it is discovered automatically from app/Console/Commands β€” there is no Kernel file to register it in anymore. Give it a $signature like app:greeting and it appears in php artisan list.

Running & Building

The development server

Laravel ships with a built-in PHP server, so you can start coding without configuring Apache or Nginx:

# Serve at http://127.0.0.1:8000
php artisan serve

# Custom host and port
php artisan serve --host=0.0.0.0 --port=8080

This server is for development only β€” think prototype workbench, not the production factory. In production you front the app with Nginx or Apache (or a managed platform).

Front-end assets with Vite

Laravel 11 uses Vite to compile the CSS and JavaScript in resources/. Install the Node dependencies once, then run the dev server for instant hot-reloading while you work:

# Install front-end dependencies (one time)
npm install

# Dev server with hot module replacement
npm run dev

# Optimized production build β†’ public/build
npm run build

Run php artisan serve and npm run dev in two terminals side by side during development: one serves your PHP, the other rebuilds assets the moment you save.

⚠️ Common setup snags

  • Permission errors β€” the storage and bootstrap/cache folders must be writable. On Linux/macOS: chmod -R 775 storage bootstrap/cache.
  • Database connection refused β€” double-check your .env credentials and that the DB server is actually running.
  • "No application encryption key" β€” run php artisan key:generate.
  • Broken asset links β€” make sure APP_URL matches the address you load in the browser.

Hands-on Exercise

πŸ‹οΈ From Zero to Welcome Page

Objective: Create a working Laravel 11 app backed by SQLite and confirm it runs.

Instructions:

  1. Create a project: composer create-project laravel/laravel demo-app.
  2. In .env, set DB_CONNECTION=sqlite and remove the other DB_* lines.
  3. Create the database file and run the default migrations.
  4. Start the server and open the welcome page in your browser.
  5. Run php artisan route:list and identify the route serving that welcome page.
πŸ’‘ Hint

After editing .env, create the SQLite file with touch database/database.sqlite (or create an empty file of that name). Then php artisan migrate will populate it. If migrate complains it can't find the database, confirm the file exists and the path is correct.

βœ… Example solution
composer create-project laravel/laravel demo-app
cd demo-app

# In .env set: DB_CONNECTION=sqlite  (delete the DB_HOST/PORT/DATABASE/USERNAME/PASSWORD lines)

touch database/database.sqlite
php artisan migrate          # builds users, cache, jobs tables
php artisan serve            # http://127.0.0.1:8000

php artisan route:list       # the "/" GET route renders welcome.blade.php

Loading http://127.0.0.1:8000 shows the Laravel welcome page. In route:list, the GET / row is the one returning welcome.

🎯 Quick Quiz

Question 1: Which file should you commit to version control to document required environment variables without leaking secrets?

Question 2: What does php artisan make:model Product -m create?

Question 3: In Laravel 11, how do you add API routing to a fresh app that has no routes/api.php?

Summary & Quiz

πŸŽ‰ Key Takeaways

  • Laravel 11 needs PHP 8.2+, Composer, a database, and Node.js for assets.
  • Create projects with Composer create-project, the Laravel installer, or Sail (Docker).
  • The directory structure separates concerns: app/ for code, routes/ for routes, database/ for schema, public/ as the single entry point.
  • The .env file holds environment-specific secrets β€” commit .env.example, never .env, and always generate an APP_KEY.
  • Migrations version your schema; Artisan scaffolds files and runs everyday tasks.
  • Use php artisan serve + npm run dev together while developing.

πŸ“š Further Reading

πŸš€ What's Next?

With a running project in hand, the next lesson is where the app comes alive: defining routes, wiring them to controllers, capturing URL parameters, and using route model binding to fetch records automatically.

πŸŽ‰ Nice work!

You have a real Laravel 11 app installed, configured, migrated, and serving. Everything from here builds on this foundation.