# How to Install Composer Laravel on a New Project: 7 Best Practices from the Source Code

> Install Composer Laravel on a new project using composer create-project. Follow 7 best practices including .env configuration and directory permissions for a smooth setup.

- Repository: [Laravel/framework](https://github.com/laravel/framework)
- Tags: best-practices
- Published: 2026-02-16

---

**The best way to install Composer Laravel on a new project is to use `composer create-project`, immediately configure your `.env` file, set proper directory permissions, and verify the installation using Laravel's built-in cache compilation commands.**

To install Composer Laravel on a new project correctly, you must follow the framework's specific bootstrap procedures and Composer event hooks. According to the `laravel/framework` source code, the installation process involves automated cache clearing, environment file loading, and permission checks designed to ensure your application starts in a clean, secure state. Following these framework-level best practices prevents common configuration errors and silent cache failures that can cause deployment issues.

## Step 1: Create a Fresh Laravel Project Using Composer

Use the `composer create-project` command to pull the `laravel/laravel` skeleton and install all dependencies. This command automatically executes Laravel's post-installation scripts.

```bash
composer create-project laravel/laravel my-app "12.*"

```

The framework registers **Composer event hooks** in [`src/Illuminate/Foundation/ComposerScripts.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/ComposerScripts.php). Specifically, the `postInstall` method (lines 22-28) triggers `clearCompiled()` to purge stale bootstrap caches immediately after package installation. This prevents "old config" bugs that occur when cached files persist across dependency changes.

## Step 2: Verify PHP Version and Required Extensions

Before running any Artisan commands, verify that your PHP version matches the constraint defined in [`composer.json`](https://github.com/laravel/framework/blob/main/composer.json) and that required extensions are enabled. The framework requires extensions such as `openssl`, `pdo_mysql`, `mbstring`, `tokenizer`, and `xml`.

In [`src/Illuminate/Foundation/Application.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Application.php) (lines 181-190), the service container registers core features only when underlying extensions exist. Missing extensions cause runtime exceptions early in the bootstrapping process, before the application can handle errors gracefully.

## Step 3: Configure the Environment File

Copy the environment template and generate a unique application encryption key:

```bash
cd my-app
cp .env.example .env
php artisan key:generate

```

The `Application` class loads the environment file via `environmentFile()` and `environmentFilePath()` methods (lines 728-740 in [`src/Illuminate/Foundation/Application.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Application.php)). The `KeyGenerateCommand` (located in [`src/Illuminate/Foundation/Console/KeyGenerateCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Console/KeyGenerateCommand.php)) writes a fresh `APP_KEY` to your `.env` file, which is required for signed cookies, encrypted data, and queued closures.

## Step 4: Set Proper File Permissions

Laravel caches configuration, routes, and compiled services in `storage/framework` and `bootstrap/cache`. If these directories are not writable, the framework's `clearCompiled()` routine (called by Composer scripts) will silently fail.

```bash
sudo chown -R $USER:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache

```

The `clearCompiled()` method in [`src/Illuminate/Foundation/ComposerScripts.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/ComposerScripts.php) (lines 95-115) attempts to delete cached config, services, and packages files. Without write permissions, stale caches persist and cause configuration mismatches.

## Step 5: Start the Development Server (Optional)

Validate your installation by running the built-in development server:

```bash
php artisan serve

```

The `ServeCommand` (found in [`src/Illuminate/Foundation/Console/ServeCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Console/ServeCommand.php), lines 128-148) watches the `.env` file for changes and reloads the server when the environment is updated. This ensures you are testing the exact configuration you will use in production.

## Step 6: Verify the Installation

Confirm the installation by checking the version and compiling the configuration cache:

```bash
php artisan --version
php artisan config:cache

```

The `config:cache` command compiles all configuration files into a single optimized file at [`bootstrap/cache/config.php`](https://github.com/laravel/framework/blob/main/bootstrap/cache/config.php). Running this immediately after installation validates that the environment can be bootstrapped without errors and that the cache directories have proper permissions.

## Step 7: Version Control Best Practices

Commit the `composer.lock` file to ensure reproducible dependency versions across all environments, but keep `.env` out of version control. The lock file guarantees that every environment uses identical package versions, while the environment file contains sensitive credentials that should never be committed.

## How Laravel's Composer Integration Works

Understanding the framework's internal Composer hooks helps diagnose installation issues. The `ComposerScripts` class handles three critical events:

1. **postInstall**: Clears compiled caches after initial installation
2. **postUpdate**: Purges caches after dependency updates  
3. **postAutoloadDump**: Removes optimization files when the autoloader is regenerated

The `clearCompiled()` method instantiates a new `Application` instance with `getcwd()` and removes three specific cache files:

```php
// src/Illuminate/Foundation/ComposerScripts.php – clear compiled files after install
protected static function clearCompiled()
{
    $laravel = new Application(getcwd());

    if (is_file($configPath = $laravel->getCachedConfigPath())) {
        @unlink($configPath);
    }

    if (is_file($servicesPath = $laravel->getCachedServicesPath())) {
        @unlink($servicesPath);
    }

    if (is_file($packagesPath = $laravel->getCachedPackagesPath())) {
        @unlink($packagesPath);
    }
}

```

During bootstrap, the `LoadEnvironmentVariables` class (located in [`src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php)) reads the file name from `environmentFile()` and resolves its full path via `environmentFilePath()`:

```php
// src/Illuminate/Foundation/Application.php – environment handling
public function environmentFile()
{
    return $this->environmentFile ?: '.env';
}

public function environmentFilePath()
{
    return $this->environmentPath().DIRECTORY_SEPARATOR.$this->environmentFile();
}

```

If you rename the environment file, you must update the bootstrapper or pass `--env` to Artisan commands.

## Summary

- **Use `composer create-project`** to install Laravel and trigger automatic cache clearing via [`ComposerScripts.php`](https://github.com/laravel/framework/blob/main/ComposerScripts.php)
- **Verify PHP extensions** before installation to prevent bootstrap failures in [`Application.php`](https://github.com/laravel/framework/blob/main/Application.php)
- **Copy `.env.example` to `.env`** and run `key:generate` to set up encryption keys required for security features
- **Set 775 permissions** on `storage` and `bootstrap/cache` to allow `clearCompiled()` to function correctly
- **Run `config:cache`** immediately after installation to validate the bootstrap process and optimize configuration loading
- **Commit `composer.lock`** but exclude `.env` from version control for reproducible, secure deployments
- **Use `php artisan serve`** for development, which watches `.env` changes via `ServeCommand`

## Frequently Asked Questions

### What is the correct command to install Composer Laravel for production?

Use `composer create-project laravel/laravel project-name --no-dev` to omit development dependencies. According to the framework's [`ComposerScripts.php`](https://github.com/laravel/framework/blob/main/ComposerScripts.php), the installation still runs `clearCompiled()` to ensure no stale caches exist, but skips dev-only packages that should not deploy to production environments.

### Why does Laravel require write permissions on the storage directory?

The framework writes compiled configuration, route caches, and service manifests to `storage/framework` and `bootstrap/cache`. The `clearCompiled()` method in [`ComposerScripts.php`](https://github.com/laravel/framework/blob/main/ComposerScripts.php) attempts to delete these files during installation and updates. Without write permissions, these operations fail silently, causing the application to load outdated cached configuration instead of fresh environment variables.

### How does Laravel handle the environment file during installation?

The `Application` class defines `environmentFile()` and `environmentFilePath()` methods (lines 728-740 in [`src/Illuminate/Foundation/Application.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Application.php)) to locate and load the `.env` file. The `LoadEnvironmentVariables` bootstrapper reads this file during the boot process. You must copy `.env.example` to `.env` before running any Artisan commands, as the framework attempts to load environment variables immediately upon instantiation.

### What happens if I don't run `php artisan key:generate` after installing Laravel?

Without generating an `APP_KEY`, the framework cannot encrypt cookies, session data, or sensitive configuration values. The `KeyGenerateCommand` (in [`src/Illuminate/Foundation/Console/KeyGenerateCommand.php`](https://github.com/laravel/framework/blob/main/src/Illuminate/Foundation/Console/KeyGenerateCommand.php)) generates a 32-character random string and writes it to the `.env` file. Missing or invalid keys cause runtime exceptions when the application attempts to use Laravel's encryption services.