PHPackages                             devkit/env-profiles - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. devkit/env-profiles

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

devkit/env-profiles
===================

Save, switch, and diff .env profiles — named store, backups, gitignore hints, and drift reports.

v1.0.3(1mo ago)049↑76.5%MITPHPPHP ^8.3

Since Apr 18Pushed 1mo agoCompare

[ Source](https://github.com/stuarttodd-dev/devkit-env-profiles)[ Packagist](https://packagist.org/packages/devkit/env-profiles)[ Fund](https://buymeacoffee.com/stuarttodd)[ RSS](/packages/devkit-env-profiles/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (7)Versions (6)Used By (0)

 [![Devkit Profiles](./devkit-logo.png)](./devkit-logo.png)devkit-env-profiles
===================

[](#devkit-env-profiles)

Named `.env` profiles, safe switching with backups, and drift reports — all from one Composer binary.

[![PHP](https://camo.githubusercontent.com/38027453aeb7eb818641c9de8f82b7624c3558d92634f1946edc715c3ddf8956/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![Packagist](https://camo.githubusercontent.com/6589e650fdf2c8f35dea3694536c661ee7ae513d0bd6c5ee54474231c1e18190/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6465766b69742f656e762d70726f66696c65733f6c6162656c3d7061636b616769737426636f6c6f723d663238643161266c6f676f3d7061636b6167697374266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/devkit/env-profiles)[![License](https://camo.githubusercontent.com/3dbbde5f79a33abd50d80ee2476ee9236804a30aea2f11009a427a50ac6ef76c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d323263353565)](LICENSE)[![Tests](https://github.com/stuarttodd-dev/devkit-env-profiles/actions/workflows/tests.yml/badge.svg)](https://github.com/stuarttodd-dev/devkit-env-profiles/actions)

---

Table of Contents
-----------------

[](#table-of-contents)

- [Why this exists](#why-this-exists)
- [Use case — switching environments in seconds](#use-case--switching-environments-in-seconds)
- [Prerequisites](#prerequisites)
- [Install](#install)
- [Running the CLI](#running-the-cli)
- [Commands at a glance](#commands-at-a-glance)
- [Configuration](#configuration)
- [Files and folders](#files-and-folders)
- [Commands](#commands)
    - [`save`](#save--snapshot-a-file-into-a-named-profile)
    - [`use`](#use--apply-a-profile-to-your-working-env-file)
    - [`list`](#list--show-saved-profile-names)
    - [`delete`](#delete--remove-a-profile-from-the-store)
    - [`diff`](#diff--drift-between-env-files)
    - [`merge`](#merge--combine-two-env-files)
- [Library API](#library-api)
- [Development](#development)
- [Support](#support)
- [License](#license)

---

Why this exists
---------------

[](#why-this-exists)

Managing several environments usually means several files: `.env`, `.env.staging`, secrets in CI, and the nagging question — *"does production still match what we think?"*

This tool gives you a **small profile store** under your repo, a **predictable `use` workflow** (with backups and optional post-switch hooks), and a **`diff` command** to compare any set of env files side by side or as JSON.

---

Use case — switching environments in seconds
--------------------------------------------

[](#use-case--switching-environments-in-seconds)

Imagine a typical Laravel app: local dev uses SQLite and the local filesystem, staging uses MySQL and S3-compatible storage, production uses RDS Aurora, S3, and a Redis queue. Without a tool like this, switching means manually editing `.env`, hunting down the right values, and hoping you didn't leave `APP_DEBUG=true` pointing at production.

With `devkit-env-profiles`:

```
# One-time setup: snapshot each environment into a named profile
./vendor/bin/devkit-env save local
./vendor/bin/devkit-env save staging
./vendor/bin/devkit-env save production
```

Then switching is a single command — with an automatic backup and optional post-switch hooks (cache clear, migrations, etc.) running for you:

```
./vendor/bin/devkit-env use staging
# ✔ Backup of .env written to env/backups/
# ✔ staging profile applied to .env
# ✔ php artisan config:clear
# ✔ php artisan cache:clear

./vendor/bin/devkit-env use production
# ✔ Backup of .env written to env/backups/
# ✔ production profile applied to .env
# ✔ php artisan config:clear
# ✔ php artisan cache:clear
# ✔ php artisan migrate --force --no-interaction
```

And when something feels off, `diff` tells you exactly what diverged:

```
./vendor/bin/devkit-env diff local production --format side-by-side
```

```
KEY               local               production
────────────────────────────────────────────────
DB_CONNECTION     sqlite              mysql
FILESYSTEM_DISK   local               s3
QUEUE_CONNECTION  sync                redis
CACHE_DRIVER      file                redis
LOG_LEVEL         debug               — missing —

```

The profiles live outside version control (auto-added to `.gitignore`) so secrets never accidentally land in your repo.

---

Prerequisites
-------------

[](#prerequisites)

RequirementVersionPHP**8.3+**Composerany recent---

Install
-------

[](#install)

```
composer require --dev devkit/env-profiles
```

From a clone of this repo```
composer install
```

---

Running the CLI
---------------

[](#running-the-cli)

The CLI resolves **paths** and **`.devkit-env.json`** relative to the directory you run it from. Always run from your **application root** (where `composer.json` and usually `.env` live).

```
# Recommended
./vendor/bin/devkit-env --help

# Alternatives
composer exec devkit-env -- --help
php vendor/bin/devkit-env --help
```

> **Windows:** use `vendor\bin\devkit-env.bat` or `php vendor\bin\devkit-env`.

---

Commands at a glance
--------------------

[](#commands-at-a-glance)

CommandWhat it does`save`Snapshot `./.env` (or `--from`) into a named profile.`use`Apply a saved profile to your working `.env`, with automatic backup.`list`Print all saved profile names.`delete`Remove a profile from the store (does not touch your live `.env`).`diff`Compare profiles or files; shows missing keys, extra keys, and value drift.`merge`Merge two env files or profiles; interactive or scriptable.---

Configuration
-------------

[](#configuration)

Drop a **`.devkit-env.json`** in your project root to customise store paths and post-switch hooks.

> **Note:** `defaultEnv` and `targetEnv` only affect `use`. When `save` runs without `--from`, it always reads `./.env` — not these keys.

```
{
  "storeDir": "env",
  "backupDir": "env/backups",
  "defaultEnv": ".env",
  "afterSwitch": [
    "php artisan config:clear",
    "php artisan cache:clear"
  ],
  "afterSwitchProfiles": {
    "production": [
      "php artisan migrate --force --no-interaction"
    ]
  }
}
```

KeyRole`storeDir`Directory for saved profile files and `registry.json`.`backupDir`Where `use` stores timestamped backups of the replaced file.`defaultEnv`Path `use` writes a profile to (often `.env`). Relative unless absolute.`targetEnv`Same as `defaultEnv`; if both are set, **`targetEnv` wins**.`afterSwitch`Shell commands run after **every** successful `use`.`afterSwitchProfiles`Extra commands for specific profile names (runs after `afterSwitch`).Full hook example```
{
  "afterSwitch": [
    "php artisan config:clear",
    "php artisan cache:clear"
  ],
  "afterSwitchProfiles": {
    "staging": [
      "php artisan route:clear"
    ],
    "production": [
      "php artisan optimize",
      "php artisan config:cache"
    ]
  }
}
```

```
./vendor/bin/devkit-env use staging      # runs afterSwitch + staging hooks
./vendor/bin/devkit-env use production   # runs afterSwitch + production hooks
./vendor/bin/devkit-env use staging --skip-hooks  # skip all hooks
```

---

Files and folders
-----------------

[](#files-and-folders)

```
env/                   **Interactive (TTY):** run `use` without a name to pick from a numbered list.

---

### `list` — show saved profile names

[](#list--show-saved-profile-names)

```
./vendor/bin/devkit-env list
```

Prints one name per line, or `(no profiles saved yet)` if the store is empty.

---

### `delete` — remove a profile from the store

[](#delete--remove-a-profile-from-the-store)

```
./vendor/bin/devkit-env delete staging          # prompts for confirmation
./vendor/bin/devkit-env delete staging --force  # skip confirmation
```

> **Interactive (TTY):** run `delete` without a name to pick from a list.

---

### `diff` — drift between env files

[](#diff--drift-between-env-files)

Compares a **baseline** against one or more **targets**: missing keys, extra keys, and mismatched values. Sensitive-looking values are masked by default.

```
# Using saved profiles
./vendor/bin/devkit-env diff local staging
./vendor/bin/devkit-env diff local staging production

# Using explicit file paths
./vendor/bin/devkit-env diff \
  --baseline=local \
  --env local=examples/env/local.env \
  --env staging=examples/env/staging.env \
  --env production=examples/env/production.env

# Output formats
./vendor/bin/devkit-env diff local staging --format text
./vendor/bin/devkit-env diff local staging --format json
./vendor/bin/devkit-env diff local staging --format side-by-side

# Masking
./vendor/bin/devkit-env diff local staging --no-mask
./vendor/bin/devkit-env diff local staging --mask-key 'APP_*' --mask-key 'STRIPE_*'
```

**Exit codes:** `0` = no drift · `1` = drift found · `2` = error

---

### `merge` — combine two `.env` files

[](#merge--combine-two-env-files)

```
# Merge two saved profiles (interactive confirm before overwrite)
./vendor/bin/devkit-env merge local staging

# Merge explicit files to an output file
./vendor/bin/devkit-env merge \
  --left examples/env/local.env \
  --right examples/env/staging.env \
  --out merged.env

# Print to stdout
./vendor/bin/devkit-env merge --left .env --right .env.staging

# Non-interactive (CI-friendly)
./vendor/bin/devkit-env merge --left .env --right .env.staging -n --prefer right --out merged.env

# Dry run
./vendor/bin/devkit-env merge --left .env --right .env.staging --dry-run

# Tickbox selection mode (interactive checklist of right-side changes)
./vendor/bin/devkit-env merge --left .env --right .env.staging --select
```

`--select` keybindingsKeyAction`1`–`N`Toggle item`a`Select all`n`Select none`v`Toggle value previews`d`Done`q`Cancel---

Library API
-----------

[](#library-api)

Most users only need the CLI. If you want to integrate programmatically:

```
require __DIR__ . '/vendor/autoload.php';

// Devkit\Env\Diff\EnvFileParser
// Devkit\Env\Store\ProjectConfig::load()
```

NamespaceContents`Devkit\Env\Diff\`Parsing, comparison, masking, report formatters.`Devkit\Env\Store\`Config, profile save/apply/list/delete, registry, gitignore hooks, post-switch runner.---

Development
-----------

[](#development)

```
composer run tests
composer run standards:check
```

---

Support
-------

[](#support)

If this project saves you time, consider buying me a coffee:

[![Buy Me a Coffee](https://camo.githubusercontent.com/2d46bf14a397821eb518fb5a37197f9a4fbff0ddcb1734dfe2e0211a942e4b10/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275792532304d6525323061253230436f666665652d737570706f72742d4646444430303f6c6f676f3d6275792d6d652d612d636f66666565266c6f676f436f6c6f723d626c61636b)](https://buymeacoffee.com/stuarttodd)

---

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance91

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

4

Last Release

52d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/54860041?v=4)[Stuart Todd](/maintainers/stuarttodd-dev)[@stuarttodd-dev](https://github.com/stuarttodd-dev)

---

Top Contributors

[![stuarttodd-dev](https://avatars.githubusercontent.com/u/54860041?v=4)](https://github.com/stuarttodd-dev "stuarttodd-dev (3 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/devkit-env-profiles/health.svg)

```
[![Health](https://phpackages.com/badges/devkit-env-profiles/health.svg)](https://phpackages.com/packages/devkit-env-profiles)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.7k532.1M19.2k](/packages/laravel-framework)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k11](/packages/tempest-framework)[azuracast/azuracast

The AzuraCast self-hosted web radio station management suite.

3.9k27.8k](/packages/azuracast-azuracast)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

744284.3k34](/packages/civicrm-civicrm-core)[cognesy/instructor-php

The complete AI toolkit for PHP: unified LLM API, structured outputs, agents, and coding agent control

317117.1k1](/packages/cognesy-instructor-php)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45344.0k1](/packages/pressbooks-pressbooks)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
