I Was DEFINITELY Using The Wrong Dev Env CLI
|
This issue is brought to you by:
Teleport: Unified Identity Securing Classic & AI Infrastructure
Teleport unifies identities — humans, machines, and AI — with strong identity implementation to speed up engineering, improve resiliency against identity-based attacks, and secure AI in production infrastructure.
|
|
I titled this newsletter like I did because I realized my old setup was a fragmented mess of five different tools when it could have been one.
I learned that managing runtimes, env vars, and task runners separately is not only a waste but also extremely hard when collaborating with others.
Mise (short for mise-en-place, which is a French culinary term for "everything in place") finally brings everything into one tiny, lightning-fast Rust binary that doesn't rely on the complexity of Nix.
Now, I'm fully aware that the last sentence might bring some heat, but, I already said my piece.
The best way to start is to stop using manual version managers and move your project settings into a single config file.
You can replace your messy Makefiles and complicated Docker setups for local development with a clean system that works the same way on your machine as it does in your CI pipeline (I'm not exaggerating, wait and read through).
By putting these learnings into action, you can automate your entire environment setup so that any new developer on your team can get started with just one command.
One command that runs a local dev env, pins versions, installs utilities, integrates scripts, reads secrets, loads variables, aaaaaand does everything, automatically. Right when you enter the project.
We have all been there when joining a new project.
You open the README and see a massive list of dependencies to install manually.
You have to hunt down specific versions of Node, set up local environment variables, and pray that your global Python version doesn't break the build.
It is a huge waste of time that turns a five-minute task into a three hour (if you're lucky) debugging session of your own terminal.
It feels like we are spending more time managing our tools than actually writing any code.
We usually reach for Docker and Nix
Most people try to solve this by reaching for heavy-duty tools like Docker or Nix.
They build giant containers to isolate everything or use things like Devbox (great option by any standard) to wrap around the complexity of the Nix ecosystem.
Others stick to the classic combination of a Makefile for scripts and Direnv for loading secret keys.
It feels like the professional way to do things because it is what everyone else is doing.
We just accept that the overhead is the price we pay for a working environment.
These tools often add more friction than they fix
The problem is that these solutions often come with their own hoops to jump through.
Docker is heavy and can feel sluggish for local development.
Not to mention having to mount a path, and having to `exec` in every time you need to make a change, and of course, not having your local shell with you.
Nix is incredibly powerful but has a steep learning curve that can give you Nix trauma when things go wrong (don't ask me how how I know).
Even great tools like Devbox still require you to have Nix installed in the background, which adds another layer of management you probably do not want.
If you're like me and use a hipster shell like Nushell, many of these tools don't even support you out of the box, leaving you to hack together your own configs.
Mise is the tiny Rust tool that does it all
Mise is a single tool written in Rust that handles your runtimes, your env vars, and your tasks all at once.
It is not a Nix wrapper, it is doing its own thing, which makes it incredibly fast and lightweight.
It has its own registry of tools, but it can also plug into other backends like homebrew, cargo, or even go.
It even includes a task system that is so robust it can function as your entire CI system.
To get started, you can install the tool using a simple curl command:
You can verify that everything is installed correctly and see your system architecture
If you want to run a specific tool version once without installing it, you can use the exec command
mise exec python@3.12 -- python
To pin a specific tool version to your current project, run:
To make sure Mise automatically loads your tools and variables whenever you enter the directory, you need to activate it in your shell:
# not an actual command to run, but rather generating a script to $(eval)
mise activate
If you want a specific tool version to be available everywhere on your machine, you can set it globally:
Mise allows you to define and run custom tasks that are stored in your project configuration:
# after setting a [task.build] in your toml file:
mise run build
If you forget what scripts are available in a project, you can list them all out easily:
You can even generate configurations for things like GitHub Actions or dev containers based on your Mise setup:
Beyond just tools, Mise handles environment variables and integrates with secret managers like SOPS, age and even using fnox, and open source from the save author that can connect you to secret managers on cloud platforms or other options like 1Password and so on.
Your "works on my machine" excuses are officially over.
I hope this was valuable! Thank you for reading.
Feel free to reply directly with any question or feedback.
Have a great weekend!
Whenever you’re ready, here’s how I can help you:
|
|