Show HN: Envelope – A modern environment variable cli tool (github.com)
I had this idea when I made a big mistake and broke some production stuff because I had a very messy .env file laying around in my project.
I was implementing new features for one of my projects and in my .env file I had the test database url commented out and the production one was not. Long story short, I applied migrations to the production database instead of my local test one and broke a lot of production APIs :')
I wanted a tool that could easily help me spot these issues before something bad happened, and so I built envelope for that reason.
Instead of a \.env(\..+)? file, I now use this tool to add variables to different configurations: dev, prod etc. and I feed them to the program I am executing on a one liner.
$ envelope init
$ envelope add dev db_url localhost:5432/postgres
$ envelope add dev db_username username
$ envelope add dev db_pwd pwd
$ export $(envelope list dev)
$ ./run.sh
This way I am explicitly exporting the dev environment without relying on the fact that everything is in order in my .env file (another approach would be to have a .env.dev file)A very useful feature that I use quite a lot is the `check` command which is going to tell you which environment you have currently active
$ export $(envelope list dev)
$ envelope check
> dev
I don't think this tool is going to be useful to anybody, but I wanted to share this with you in case there is someone that can make good use of it or find particular scenarios where this could be used instead of .env files, either way I had a lot of fun building it
57 comments
[ 109 ms ] story [ 2011 ms ] thread> I used to have a `brew tap` for it but I've removed it temporarily. To install it you can download the binary file in the latest release[0] and move it to your `/usr/local/bin` folder (on macOS this is what I'd do) or any other folder that is in your `$PATH`.
[0]: https://github.com/mattrighetti/envelope/releases/latest
Env variables should be a solved problem but no one has made the simplest general solution yet. Seems like you are on track.
One suggestion: no need to use SQLite. Just develop a simple (and _lasting_), plain text DSL and save to a file.
Here's one I made using your example.
https://sdk.scroll.pub/designer/#parsers%0A%20valueCell%0A%2...
I'm happy to chat more to nail that design if that would be helpful.
Environment variables aren't only for secrets (some say they should have never been).
The reason why we even pull these things out in the first place is because they're considered dynamic values. Otherwise we'd just hardcode them in a committed constants file.
Interesting article just about that [0]
[0]: https://garrit.xyz/posts/2023-11-01-tracking-sqlite-database...
At some point I may clean up the code so that it can really shine.
Higher priority though is getting support for this Parsers language in Sublime and VS Code.
I think the main problem is that this problem is 99% solved by the shell alone. Shells are very versatile and it is quite easy to setup different environments using your shell. I'd bet that the crossover of people good at manipulating environments on workstations and people good with shells is pretty big. That is, the people with good domain knowledge have little motivation to write tools to address this.
Have you looked at mise-en-place at all? It's written in rust too, and might have some cool ideas to use: https://mise.jdx.dev/
If you do a lot of remote pairing or screen sharing then you also remove the risk of sharing on accident by searching or walking up through your command history.
Very common these days. I don’t get it.
For instance, I have a migrations library that I descibre as "modern" because it is designed for a continuous deployment environment where you're automatically running migrations on container startup — there are tons of existing popular migrations libraries, but none of them work this way because they were written in the era that you'd manually run sql commands in prod. I say "modern" so that if anyone finds my library, they realize that it was created recently based on more recent dev/ops trends.
Maybe I should drop the "modern"? I do see a lot of people describe their code as "minimal" or "clean", which is pretty meaningless to me, so I get that "modern" could come across that way as well.
I think you should drop “modern” for something like “designed for CI”, “CI-first” or “CI-native”. It’s more informative.
Its interface is designed to be an almost drop-in replacement of grep, which makes it "old style".
I think software can be old style, modern, or neutral. Most software written today aims for modern, it seems logical.
Actually, they are not applied. This is a tool that helps you manage them, you can see it as a replacement of .env files.
> `envelope check` could be replaced with a CURRENT_ENV environment variable in an .env file
Can you elaborate more on this? I've never used that tbh and I'm interested
The point of .env files is for tools (shells or libraries like dotenv) to read the file and actually use them. How do you do that with your tool, considering it uses a custom format?
> Can you elaborate more on this? I've never used that tbh and I'm interested
There is nothing special, just define a variable in .env, and then either echo it manually, or change your shell prompt to apply it.
I feel like this is a giant red flag. Why on earth is your production database accessible from anywhere (ie your PC) without some kind of extra layer of security like a VPN or SSH tunnel?
What did you find lacking with the .env.dev approach? (Or if some tool doesn't support .env.dev could always symlink .env → .env.dev)
To each their own, though!
Is there a way to use envelope in places like those?