I wrote a env-profiler package.
Stop copying .env files. Start switching profiles.
If you’re anything like me (and if not, lucky you), you’re constantly switching environment variables.
Different clients mean different setups:
different databases.
different feature flags.
slightly different configs that definitely matter.
So testing locally turns into manually tweaking your .env file over and over again.
It’s clunky. It’s error-prone. It’s a pain.
What I actually want is simple:
Save an environment profile, switch to it when I need it, then switch back.
That’s it.
env-profile package
So yeah, I built a package. It saves me minutes every day or two (Hey, it all adds up!). It’s easy enough to install.
composer require devkit/env-profilesOnce installed, you’ve got a help flag.
./vendor/bin/devkit-env --helpIt tells you what you can do with some examples:
./vendor/bin/devkit-env — switch between saved .env profiles and compare environments.
Commands:
diff Compare .env files (drift report). Run: ./vendor/bin/devkit-env diff --help
merge Merge two .env files (interactive or --prefer). Run: ./vendor/bin/devkit-env merge --help
save Copy ./.env (or --from PATH) into a named profile under ./env/
use Apply a named profile onto defaultEnv/targetEnv from .devkit-env.json (with backup by default)
list List saved profile names
delete Remove a saved profile
Configuration (optional): .devkit-env.json in the project root
storeDir, backupDir, defaultEnv (or targetEnv), afterSwitch, afterSwitchProfiles — see README.
Examples:
./vendor/bin/devkit-env save staging
./vendor/bin/devkit-env save --name staging --from .env.staging
./vendor/bin/devkit-env use staging
./vendor/bin/devkit-env diff --baseline=local --env local=.env --env prod=.env.prodLet’s go through them!
save - Create a profile
This takes your current .env (or another file) and stores it as a named profile.
./vendor/bin/devkit-env save stagingOr from a specific file:
./vendor/bin/devkit-env save --name staging --from .env.stagingWhy this matters
Instead of keeping random .env.* files lying around…
You now have named, intentional profiles.
use - Switch environments
This is the one you’ll use the most.
./vendor/bin/devkit-env use stagingIt applies the saved profile to your active .env.
What it does for you
switches environment instantly
creates a backup (so you don’t lose anything)
removes the need to manually copy files
This is the “stop copying .env files” command.
list - See what you’ve got
./vendor/bin/devkit-env listShows all saved profiles.
Why it matters
Because after a while you forget what you’ve created.
This keeps things visible and organised.
delete - Clean up
./vendor/bin/devkit-env delete stagingRemoves a profile you don’t need anymore.
Why it matters
Because otherwise you end up with:
“staging-final-final-please-delete-this”
diff - Spot problems
./vendor/bin/devkit-env diff --baseline=local --env local=.env --env prod=.env.prodThis compares environments and shows differences.
Why it matters
This is where things get interesting.
You can:
detect drift between environments
spot missing variables
catch config inconsistencies early
This is the “why does production behave differently?” tool.
merge - Combine environments
./vendor/bin/devkit-env merge --helpLets you merge two .env files, either interactively or with rules.
Why it matters
Sometimes you don’t want to overwrite.
You want to:
combine configs
resolve differences
keep control
This gives you that option.
Optional Config
You can define behaviour in a .devkit-env.json file.
Things like:
where profiles are stored
where backups go
which
.envfile is targetedscripts to run after switching
Here’s an example:
{
"storeDir": "env",
"backupDir": "env/backups",
"defaultEnv": ".env",
"afterSwitch": [
"php artisan config:clear",
"php artisan cache:clear"
],
"afterSwitchProfiles": {
"production": [
"php artisan migrate --force --no-interaction"
]
}
}You don’t need it to get started, but it’s there if you want control. In this example, after switching profile we’d run:
php artisan config:clear
php artisan cache:clearThen if the profile is production:
php artisan migrate --force --no-interactionUseful, right? Clearing cache etc. No problem.
What This Actually Solves
This isn’t about adding more tooling.
It’s about removing friction.
Before:
copy
.envfilesforget values
debug nonsense
After:
save profile
switch profile
move on
The Real Benefit
It’s not the time saved. It’s the mental load removed.
You stop thinking:
“what’s currently in my
.env?”
And start thinking:
“which environment am I using?”
That’s a much cleaner model.
Final Thought
We’ve all accepted a weird workflow for too long:
duplicate config files
manually copy them
hope everything lines up
This just replaces that with something intentional.
Check it out
https://packagist.org/packages/devkit/env-profiles
P.S - I’m creating a few more!


