4 comments

  • theozero 12 hours ago ago

    You might like varlock (https://varlock.dev)

    You can use it to declaratively fetch from various backends, but it’s optional. At its core it lets you create a .env.schema and you get validation, type safety, guardrails for sensitive values, and a flexible toolkit to deal with all config related headaches.

    The big difference from your tool (and many others) is that instead of trying to provide tooling to keep an example and other files in sync, the schema file is part of the loading process, so it can never be out of sync. This also helps create a single source of truth, and helps create a unified system to deal with all config - both sensitive and not.

  • xserhio 10 hours ago ago

    Thanks for sharing varlock, it looks really solid! The .env.schema approach is a great way to guarantee strict type safety and a single source of truth.

    I think the main philosophical difference here is where the validation happens. If I understand correctly, varlock integrates directly into the application's config loading process. That’s incredibly powerful for runtime safety.

    My goal with env-rx was to build something completely detached from the application runtime. I wanted a drop-in CLI utility that requires absolutely zero code changes or new dependencies in the actual app. You just throw it into a GitHub Action or a pre-commit hook, and it screams at you if a variable is missing before the code even builds.

    But I really like your approach to having a unified schema instead of just comparing against an .example file. Definitely taking some notes from how varlock handles this!

    • theozero 9 hours ago ago

      Thanks for the kind words. It's actually decoupled and up to the user if they want to use it for pure validation as part of CI/deployment, just to inject values, or to integrate more deeply. But you can get the most benefit by integrating it fully. This lets you set values, compose values using functions, take advantage of coercion, and helps protect your secrets.

      You can just use `varlock run -- ...your command` and it will load, validate, and reinject as env vars. This is what enables it to be used with any language or any tool. We have a standalone binary. You could also just use `varlock load` to do validation and rely on values all being set externally. However we do provide javascript helpers to just load everything automatically - although this just calls out to the CLI, keeping your app isolated from the code that loads and validates the vars. For JS we actually go a bit further and patch http and console to protect any sensitive data - because we know exactly which config items are sensitive.

      It's really meant to just be a complete complete toolkit and then let users integrate as deep as they want to.

      • xserhio 7 hours ago ago

        Ah, I stand corrected! The varlock run -- approach and the standalone binary completely solve the vendor lock-in concern I mentioned.

        I have to say, patching console and http in JS to auto-redact sensitive data based on the schema is genuinely brilliant. Leaking secrets in logs is a massive pain point, and handling it automatically at the tool level is a great solution.

        Really impressive work on the entire toolkit. It’s definitely a much more comprehensive ecosystem than what I built. I appreciate you taking the time to explain the architecture—definitely taking some notes from this!