{"id":21831764,"url":"https://github.com/wuespace/envar","last_synced_at":"2026-04-13T23:03:45.494Z","repository":{"id":260001206,"uuid":"880009312","full_name":"wuespace/envar","owner":"wuespace","description":"🚀 Envar makes it easy to add configurability to your Deno applications. It supports loading configuration from environment variables as well asspecifying default values.","archived":false,"fork":false,"pushed_at":"2024-12-07T15:36:27.000Z","size":72,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-21T00:08:10.857Z","etag":null,"topics":["configuration","deno","docker","docker-configuration","docker-secrets","environment","environment-variables","initvariable","jsr","library","package","typescript","validation","zod"],"latest_commit_sha":null,"homepage":"https://jsr.io/@wuespace/envar","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wuespace.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-29T00:20:59.000Z","updated_at":"2024-12-07T21:17:10.000Z","dependencies_parsed_at":"2024-12-07T16:23:57.342Z","dependency_job_id":null,"html_url":"https://github.com/wuespace/envar","commit_stats":null,"previous_names":["wuespace/envar"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuespace%2Fenvar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuespace%2Fenvar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuespace%2Fenvar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wuespace%2Fenvar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wuespace","download_url":"https://codeload.github.com/wuespace/envar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244804223,"owners_count":20513071,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","deno","docker","docker-configuration","docker-secrets","environment","environment-variables","initvariable","jsr","library","package","typescript","validation","zod"],"created_at":"2024-11-27T19:15:28.060Z","updated_at":"2026-04-13T23:03:45.456Z","avatar_url":"https://github.com/wuespace.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @wuespace/envar\n\n[![JSR Scope](https://jsr.io/badges/@wuespace)](https://jsr.io/@wuespace)\n[![JSR](https://jsr.io/badges/@wuespace/envar)](https://jsr.io/@wuespace/envar)\n[![JSR Score](https://jsr.io/badges/@wuespace/envar/score)](https://jsr.io/@wuespace/envar)\n[![Deno CI](https://github.com/wuespace/envar/actions/workflows/deno-ci.yml/badge.svg)](https://github.com/wuespace/envar/actions/workflows/deno-ci.yml)\n[![Publish Workflow](https://github.com/wuespace/envar/actions/workflows/publish-jsr.yml/badge.svg)](https://github.com/wuespace/envar/actions/workflows/publish-jsr.yml)\n\n🚀 **Envar** makes it easy to add configurability to your Deno applications.\nIt supports loading configuration from environment variables as well as\nspecifying default values.\nIt even supports configuration values from files specified by environment\nvariables to provide first-class support for [secrets and the like in your Docker Swarm or Kubernetes deployments](https://docs.docker.com/engine/swarm/secrets/#build-support-for-docker-secrets-into-your-images).\n\n## 📦 Usage\n\nYou can use Envar in your Deno application by importing it from the\n`jsr:@wuespace/envar` module.\n\n\u003e [!NOTE]\n\u003e When you want to use envar in a bigger application, you should consider installing it using `deno add jsr:@wuespace/envar` to make sure you have a fixed version.\n\n```tsx\n// Import the initVariable function from the module\nimport { initVariable, EnvNotSetError } from \"jsr:@wuespace/envar\";\nimport { z } from \"npm:zod\";\n\n// Initialize the application variables\nawait initVariable(\"PORT\", z.string().match(/^[0-9]{1,5}$/), \"8080\");\nawait initVariable(\"SECRET\", z.string().min(32));\n// At this point, we can rest assured that we have valid values for\n// PORT and SECRET. Otherwise, the promises would have been rejected.\n\n// Access the variables like you normally would.\n// Everything's synchronous now, so it's quite easy.\nconsole.log(Deno.env.get(\"PORT\"));\nconsole.log(Deno.env.get(\"SECRET\"));\n\n// For type safety, you'll need to check if it's undefined:\nconst port = Deno.env.get(\"PORT\");\nif (port == undefined) {\n    // Automatically generate a nice error message for the user\n    throw new EnvNotSetError(\"PORT\");\n}\n\n// Alternatively, you can also use process.env in Deno 2.0+\nconsole.log(process.env.PORT);\n```\n\n\u003e [!WARNING]\n\u003e Do not access `Deno.env.get()` or similar functions at the top level of another module. Due to the import order, the environment variables may not have been initialized at that point. However, accessing the environment variable on-demand inside functions is not a big issue, as it is a synchronous operation.\n\n## 🔍 Variable Sources\n\nBut why does `initVariable` return a `Promise`? Because Envar doesn't just look at environment variables. It also supports loading variables from files. This asynchronous behavior ensures that all potential sources are checked and validated before the variable is set.\n\nLet's illustrate this with an example:\n\n```ts\nawait initVariable(\"PORT\", z.string().match(/^[0-9]{1,5}$/), \"8080\");\n```\n\nThis call attempts to load the `PORT` variable from the following sources, in order:\n\n### 🌐 Environment Variables\n\nFirst, Envar checks if an environment variable named `PORT` exists. If it does, the value is validated and used.\n\n### 📂 Files\n\nIf the `PORT` environment variable is not found, Envar looks for a variable named `PORT_FILE`. If `PORT_FILE` exists, Envar reads the file specified by this variable and uses its contents as the value for `PORT`.\n\n\u003e [!TIP]\n\u003e This follows the convention described in the [Docker Secrets documentation](https://docs.docker.com/engine/swarm/secrets/#build-support-for-docker-secrets-into-your-images).\n\n### 🛠️ Defaults\n\nIf neither an environment variable nor a file is found, the default value specified in the `initVariable` call (`\"8080\"` in this case) is used.\n\n### 🚨 Validation\n\nRegardless of the source, the value is validated using the `validator` provided in the `initVariable` call, which is typically a zod schema. If the value is invalid, an error is thrown, and the application should handle it accordingly.\n\nThe `validator` can also specify whether the variable can be `undefined` (if no value is found and there is no default value):\n\n```ts\n// Throws an error if the variable isn't set\nawait initVariable(\"SECRET\", z.string()); \n\n// Uses the default value if SECRET is not set\nawait initVariable(\"SECRET\", z.string(), 'xxx'); \n\n// Allows SECRET to be undefined without throwing an error\nawait initVariable(\"SECRET\", z.string().optional()); \n```\n\n## 🔧 Built-in Validators\n\n\u003e [!NOTE]\n\u003e This feature is available starting from version v1.1.0.\n\nEnvar provides several built-in validators to simplify common validation tasks:\n\n- `REQUIRED` - Ensures the variable is set and not `undefined`\n- `OPTIONAL` - Allows the variable to be `undefined`\n- `REQUIRED_NON_EMPTY` - Ensures the variable is set and not an empty string\n- `OPTIONAL_NON_EMPTY` - Allows the variable to be `undefined` or a non-empty string\n\nHere's how you can use these validators:\n\n```ts\nimport {\n  initVariable,\n  REQUIRED,\n  OPTIONAL,\n  REQUIRED_NON_EMPTY,\n  OPTIONAL_NON_EMPTY,\n} from \"jsr:@wuespace/envar\";\n\nawait initVariable(\"REQUIRED\", REQUIRED); // Must be set\nawait initVariable(\"OPTIONAL\", OPTIONAL); // Can be undefined\nawait initVariable(\"REQUIRED_NON_EMPTY\", REQUIRED_NON_EMPTY); // Must be set and not empty\nawait initVariable(\"OPTIONAL_NON_EMPTY\", OPTIONAL_NON_EMPTY); // Can be undefined or non-empty\n```\n\n## 🚀 Deployment Options\n\nDue to Envar's flexible source system, you have multiple options for deploying your application. We'll demonstrate these with a Docker Compose configuration, but the same principles apply to other deployment methods as well.\n\n### 💻 Application\n\n```ts\nawait initVariable(\"PORT\", z.string().match(/^[0-9]{1,5}$/), \"8080\");\nawait initVariable(\"OAUTH_TOKEN\", z.string());\nawait initVariable(\"DB_URI\", z.string().url());\nawait initVariable(\"SECRET\", z.string());\nawait initVariable(\"CONFIG\", z.string());\nawait initVariable(\"ANOTHER_SECRET\", z.string());\n\nconst rawConfig = Deno.env.get(\"CONFIG\");\nif (rawConfig == undefined) {\n    throw new EnvNotSetError(\"CONFIG\");\n}\nconst config = JSON.parse(rawConfig);\nconsole.log(config); // { key: \"value\" }\n```\n\n### 🐳 Docker Compose\n\n```yaml\nname: My Application\n\nservices:\n  my-service:\n    image: my-service\n    environment:\n      - PORT # Loaded from environment. Defaults to 8080 if not set\n      - SECRET_FILE=/run/secrets/my-secret # Mounted as secret file\n      - OAUTH_TOKEN_FILE=/run/secrets/another-secret # Mounted as secret file\n      - CONFIG_FILE=/my-service-config # Mounted as config file\n      - DB_URI=${DB_URI:-mongodb://mongo:27017/my-database} # Default value\n      - ANOTHER_SECRET=${ANOTHER_SECRET:?ANOTHER_SECRET is required} # Required variable\n    secrets:\n      - my-secret\n      - another-secret\n    configs:\n      - my-service-config\n  mongo:\n    image: mongo\n\nsecrets:\n  my-secret:\n    file: ./secret.txt # Loaded from a file\n  another-secret:\n    environment: \"OAUTH_TOKEN\" # Loaded from an environment variable\n\nconfigs:\n  my-service-config:\n      content: |\n        {\n          \"key\": \"value\"\n        }\n```\n\nThis configuration ensures that your application variables are securely managed and validated, leveraging Docker's secrets and configs features.\n\n## 👥 Authors\n\nThis package was created and is maintained by [WüSpace e. V.](https://github.com/wuespace)\n\nIts primary author is [Zuri Klaschka](https://github.com/pklaschka).\n\n## 📄 License\n\nThis package is licensed under the MIT license. See the [LICENSE](LICENSE) file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwuespace%2Fenvar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwuespace%2Fenvar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwuespace%2Fenvar/lists"}