Skip to content

About @env-spec

@env-spec is a DSL that extends normal .env syntax. It allows adding structured metadata using @decorator style comments (similar to JSDoc) and a syntax for setting values via explicit function calls.

This lets us express a declarative schema of our environment variables in a familiar format, not tied to any specific programming language or framework.

.env.schema
# Stripe secret api key
# @required @sensitive @type=string(startsWith="sk_")
# @docsUrl=https://docs.stripe.com/keys
STRIPE_SECRET_KEY=encrypted("asdfqwerqwe2374298374lksdjflksdjf981273948okjdfksdl")

Loading a schema file full of structured metadata gives us:

  • additional validation, coercion, type-safety for your env vars
  • extra guard-rails around handling of @sensitive data
  • more flexible loading logic without hand-rolled application code or config files
  • a place to store default values, clearly differentiated from placeholders

This schema information is most valuable when it is shared across team members and machines. So in most cases, this means creating a git-committed .env.schema file, instead of the familiar .env.example file used by many projects. The difference is that now the schema can be used on an ongoing basis, instead of just once to create an untracked local copy.

Building on this, you could use additional files which set values. They could add additional items or override properties of existing ones. Whether you want to use a single git-ignored .env file, or apply a cascade of environment-specific files (e.g., .env, .env.local, .env.test, etc) is up to you. However the new ability to use function calls to safely decrypt data, or load values from external sources, means you’ll likely be tempted to use git-committed .env files much more.

An env-spec enabled tool would load all env files appropriately, merging together both schema and values, as well as additional values read from the shell/process. Then the schema would be applied which could transform and fill values, for example decrypting or fetching from an external source, as well as applying coercion and validation.

This package defines a parser and related tools for parsing an @env-spec enabled .env file. It does not provide anything past this parsing step, such as actually loading environment variables.

We previously created DMNO and saw immense value in this schema-driven approach to configuration. With env-spec, we wanted to provide a standard that could benefit anyone who uses .env files (and even those who don’t!). There’s an incredible ecosystem of libraries and tools that have adopted .env, and we want to make it easier for everyone to benefit from additional guardrails, with as little upfront work as possible.

We’ve also seen the explosion of AI-assisted coding tools which means that users are even more likely to leak sensitive configuration items, like API keys. If we can help to improve the security posture for these users, then hopefully that improves things for everyone. How can I help? If you’re a maintainer, author, contributor, or an opinionated user of tools that rely on .env files, please read through our RFC. We are not trying to build in a vacuum and we want your input. We’d also love your feedback on varlock which is built on top of @env-spec since it provides (we hope!) a solid reference implementation.

If this resonates with you, please reach out. We welcome your feedback and we welcome additional contributors.