{"id":21188987,"url":"https://github.com/connorjburton/senvf","last_synced_at":"2025-07-10T02:31:33.547Z","repository":{"id":60086546,"uuid":"540623006","full_name":"connorjburton/senvf","owner":"connorjburton","description":"A secure \u0026 sensible replacement for process.env","archived":false,"fork":false,"pushed_at":"2023-01-04T20:25:01.000Z","size":211,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-01T23:36:50.317Z","etag":null,"topics":["javascript","nodejs","process-env","security","supply-chain"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/connorjburton.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-23T21:29:27.000Z","updated_at":"2024-07-05T15:05:19.000Z","dependencies_parsed_at":"2023-02-02T20:31:28.732Z","dependency_job_id":null,"html_url":"https://github.com/connorjburton/senvf","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connorjburton%2Fsenvf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connorjburton%2Fsenvf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connorjburton%2Fsenvf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connorjburton%2Fsenvf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/connorjburton","download_url":"https://codeload.github.com/connorjburton/senvf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225614626,"owners_count":17496938,"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":["javascript","nodejs","process-env","security","supply-chain"],"created_at":"2024-11-20T18:49:26.471Z","updated_at":"2024-11-20T18:49:27.185Z","avatar_url":"https://github.com/connorjburton.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](https://github.com/connorjburton/senvf/blob/master/logo.jpg)\n\n# senvf\n\nA secure \u0026 sensible replacement for `process.env`.\n\n## Why?\n\n- Most JavaScript supply chain attacks target the `process.env` object\n- It's common to see `process.env` values being used without the correct data type checks\n\n## How does this help?\n\n- Ensures `process.env` is always empty, a supply chain attack that `POST`s your `process.env` content to a remote server no longer poses a risk\n- Provides `has`/`get` helper functions\n\n## Installation\n\n**yarn**\n\n`yarn add senvf`\n\n**npm**\n\n`npm install senvf`\n\n## Documentation\n\n[View the documentation online here](https://connorjburton.github.io/senvf), or run `yarn docs` in the repository.\n\n## Usage\n\nImport `senvf` as early as possible in your codebase once `process.env` is fully set (i.e. after `import 'dotenv/config'`).\n\nOn the **first** import of `senvf` it will copy all values from `process.env` and set `process.env` to an empty object.\n\n`process.env` is proxied to set any values to the internal `senvf` object instead. [See this test](https://github.com/connorjburton/senvf/blob/master/index.test.ts#L25).\n\n```javascript\nimport \"dotenv/config\";\nimport senvf from \"senvf\";\n\nif (!senvf.has(\"DATABASE_PASSWORD\")) {\n  throw new Error(\"Database password not set\");\n}\n\nconnect({\n  host: senvf.get(\"DATABASE_HOST\", \"127.0.0.1\"),\n  password: senvf.get(\"DATABASE_PASSWORD\"),\n});\n```\n\n## FAQs\n\n**Can I set properties on `senvf`?**\n\nNo, the `senvf` object is frozen and is not meant to represent configuration. You _can_ workaround this by setting properties on `process.env` but it is **highly** advised against.\n\n**Code I use relies on `process.env` having `x` property, how can I use `senvf`?**\n\nDue to the nature of supply chain attacks, `senvf` does not allow any code to set values on `process.env`. Therefore change the code requiring `process.env` to instead accept an argument and pass the value in from `senvf.get`.\n\n**We use packages that sets values on `process.env` dynamically, how can I use `senvf`?**\n\nAny properties set on `process.env` will instead automatically be set on `senvf` by proxy, you can access those values using `senvf.get`.\n\n**Why is everything `unknown`?**\n\nProperties on `process.env` can be set to any data type. Even if you set `process.env.foo = 'bar';` there is no guarantee when you come to read `foo` that other code has not set it to another data type.\n\nFor this reason we can never guarantee the data type of the returned value of `senvf` and we do not impose any extra restrictions onto _what_ data types can be set, as we aim to be as backwards compatible as possible.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnorjburton%2Fsenvf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconnorjburton%2Fsenvf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnorjburton%2Fsenvf/lists"}