Laravel Academy
Blog / Tutorial

Tutorial

Step 2. .env and Config Files in Laravel: How They Actually Work

Why do some settings live in `.env` and others in the `config` folder, and where does your new setting belong? This tutorial explains the two-layer system behind Laravel configuration, and why calling `env()` in your controller will eventually bite you.

J

Joram

Laravel trainer & developer

27 sep 2026 · 4 min read

(Advanced — Stage 1)

Introduction

Your first Laravel project is running. Now you want to change the app name or connect a database, and you run into two things: a .env file full of uppercase variables, and a config folder full of PHP files. Which one do you edit? The good news is that there's a simple system behind it. Once you see it, you'll recognise it in every Laravel project you touch.

What you'll learn

  • The difference between .env and the files in config/
  • How a value travels from .env through a config file into your code
  • How to read settings with config()
  • How to create your own config file for your app
  • The env() mistake almost every beginner makes, and how to avoid it

Prerequisites

  • A Laravel project running locally (see Installing Laravel)
  • You can open a terminal and run a php artisan command
  • You roughly know what a PHP array is

Two layers: values and structure

Laravel configuration has two layers, each with its own job.

.env holds values that differ per environment. On your laptop you use a different database, different mail settings and a different debug mode than on your live server. Passwords and API keys go here too. That's why this file never goes into Git.

config/ holds the structure. These are plain PHP files that return an array, and they do go into Git. They define which settings your app knows about, and give each one a default value in case .env doesn't provide one.

The information always flows in one direction:

.env  →  config/*.php (via env())  →  your code (via config())

The last step is the one to remember: your code talks to config(), not to .env. You'll see why that matters further down.

Step by step

Step 1 — Look at your .env

Open .env in your project root. The top looks something like this:

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:...
APP_DEBUG=true
APP_URL=http://localhost

DB_CONNECTION=sqlite

A few values worth knowing:

  • APP_ENV: the environment your app runs in, such as local or production
  • APP_DEBUG: true gives you detailed error pages. In production, this is always false.
  • APP_KEY: the key used to encrypt sessions and cookies. Empty? Generate one:
php artisan key:generate

Next to .env you'll find .env.example. It's a template without secrets, and it does go into Git, so a colleague (or you on a new laptop) knows which variables are needed.

Step 2 — Change a value

Rename your app:

APP_NAME="Laravel Academy"

Note the quotes. Without them, a value containing a space causes an error when .env is parsed.

Step 3 — See how a config file reads .env

Open config/app.php. Among other things, you'll find:

'name' => env('APP_NAME', 'Laravel'),

'debug' => (bool) env('APP_DEBUG', false),

env('APP_NAME', 'Laravel') means: get APP_NAME from .env, and fall back to 'Laravel' if it isn't there. The second argument is your safety net.

Step 4 — Read config in your code

Anywhere in your app (a controller, a route, a Blade view) you use config() with dot notation: first the file name, then the key.

$appName = config('app.name');            // "Laravel Academy"
$database = config('database.default');   // "sqlite"

In a Blade view:

<title>{{ config('app.name') }}</title>

Want to see what Laravel actually loaded? Run:

php artisan config:show app

Or, for a general overview of your environment:

php artisan about

Step 5 — Create your own config file

If your app has its own settings, like a maximum number of students per class or a support address, give them their own file. Create config/academy.php:

<?php

return [
    'max_students_per_class' => env('ACADEMY_MAX_STUDENTS', 12),
    'support_email' => env('ACADEMY_SUPPORT_EMAIL', 'info@example.com'),
    'show_beta_banner' => env('ACADEMY_BETA_BANNER', false),
];

Add the values to .env:

ACADEMY_MAX_STUDENTS=10
ACADEMY_SUPPORT_EMAIL=support@laravel-academy.com
ACADEMY_BETA_BANNER=true

Add them to .env.example too, without real secrets:

ACADEMY_MAX_STUDENTS=12
ACADEMY_SUPPORT_EMAIL=
ACADEMY_BETA_BANNER=false

Now you can use them anywhere:

@if (config('academy.show_beta_banner'))
    <div class="banner">
        This site is in beta. Questions? Email {{ config('academy.support_email') }}
    </div>
@endif

Good to know: env() automatically converts true and false in .env into real booleans, so ACADEMY_BETA_BANNER=true works the way you'd expect.

Step 6 — Check which environment you're in

Sometimes you want something visible only locally, like a debug bar or a test button:

if (app()->environment('local')) {
    // only on your own machine
}

In Blade:

@env('local')
    <p>You're running locally.</p>
@endenv

Common mistakes

1. Using env() outside config files

This works fine locally, which is exactly what makes it dangerous:

// ❌ in a controller
$max = env('ACADEMY_MAX_STUDENTS', 12);

In production you should be running php artisan config:cache. Laravel then bundles all config into a single file and stops reading .env. Every env() call outside config/ then returns null, or your default, and your app suddenly behaves differently than it did locally. The fix:

// ✅ always go through config
$max = config('academy.max_students_per_class');

The rule of thumb: use env() only in config/, and use config() everywhere else.

2. You changed .env, but nothing changes

If you've ever run php artisan config:cache, even locally, Laravel uses that cache and ignores your .env changes. Clear it:

php artisan config:clear

3. Committing .env, or forgetting .env.example

Laravel puts .env in .gitignore by default. Leave it there, or your passwords and API keys end up in your repository. The reverse mistake is just as common: you add a new variable to .env but not to .env.example. The next person to install the project then gets an app that half-works, with no clear error.

Recap

  • .env holds per-environment values and secrets, and never goes into Git.
  • config/ holds the structure with defaults, and does go into Git.
  • Config files read .env via env(), and your code reads config via config('file.key').
  • Your own settings belong in their own config file, such as config/academy.php.
  • Never use env() outside config/, because after config:cache it returns null.

Where to go next

Now that you know where your settings live, the logical next step is actually using your database. In Connecting your database and your first migration you'll put the DB_ variables from this tutorial to work and create your first table.

Prefer learning with someone next to you when things break? In the classroom training Laravel 13 for beginners, you build a complete mini app in three days, from .env to deployment.

27 sep 2026 Tutorial