{"id":31444103,"url":"https://github.com/thefrontside/configliere","last_synced_at":"2025-10-23T19:36:14.197Z","repository":{"id":309746958,"uuid":"1037415284","full_name":"thefrontside/configliere","owner":"thefrontside","description":"Smart, FP configuration parser that validates all program inputs ahead of time, including config files, environment variables, and command line options using a single schema.","archived":false,"fork":false,"pushed_at":"2025-09-21T03:37:45.000Z","size":353,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-21T05:39:44.156Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/thefrontside.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-13T14:37:09.000Z","updated_at":"2025-08-19T23:17:41.000Z","dependencies_parsed_at":"2025-09-21T05:33:44.107Z","dependency_job_id":"d293f373-b23f-4e25-a880-3cb9ac3aa530","html_url":"https://github.com/thefrontside/configliere","commit_stats":null,"previous_names":["thefrontside/configliere"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/thefrontside/configliere","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefrontside%2Fconfigliere","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefrontside%2Fconfigliere/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefrontside%2Fconfigliere/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefrontside%2Fconfigliere/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thefrontside","download_url":"https://codeload.github.com/thefrontside/configliere/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefrontside%2Fconfigliere/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277754252,"owners_count":25871358,"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","status":"online","status_checked_at":"2025-09-30T02:00:09.208Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-09-30T20:58:02.877Z","updated_at":"2025-09-30T20:58:04.309Z","avatar_url":"https://github.com/thefrontside.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg alt=\"configliere logo\" src=\"images/configliere.jpeg\" height=\"50\"\u003e Configliere\n\nSmart, FP configuration parser that validates all program inputs ahead of time,\nincluding config files, environment variables, and command line options using a\nsingle schema.\n\n## Introduction\n\nConceptually, \"config\" is a palette of settings and switches that is accessed\nfrom various portions of our program to alter its behavior without altering its\ncode. However the story around config is often made very messy by the fact that\nit is read at _different_ times during program execution and from many\n_different_ sources such as configuration files and environment variables.\n\n\u003cimg alt=\"before configliere\" src=\"images/configliere-before.svg\" height=\"500\"\u003e\n\nAs a result, configuration is often fragile and difficult to understand. Some of\nthe symptoms of a fragmented config are:\n\n- **The deferred crash** Happens when a program begins running, perhaps even for\n  awhile, but then it reaches for a configuration value via an interface like\n  `app.getConfig(\"field\")` only to find that the value is invalid, or missing\n  altogether. Happens a lot with config files and enviroment variables.\n- **conflicting configs** When a program has more than one way of specifying the\n  same parameter, and they clobber each other.\n  - **Unclear priority** Which parameter wins? The one coming from a CLI option\n    or an environment variable?\n  - **Mysterious provenance** You can see a value for a github token, but does\n    it come from? It could be from `app-config.yaml`, or\n    `app-config.production.yaml`. Then again, it could be specified in the\n    `GITHUB_TOKEN` environment variable. But don't forget there is also a\n    `--github-token` command line option.\n  - **magical behavior** A furiously frustrating deployment-specific failure is\n    tracked down to some random environment variable overriding a parameter that\n    isn't configured like that in any other enviroment.\n- **Ad-hoc, validation** - There are different ways to verify the runtime type\n  of a configuration value depending on whether it comes from the CLI,\n  environment, or a configuration file.\n\nConfigliere solves all of these problems by re-imagining \"config\" not as a\nconstellation of globally floating objects from which we can read in values at\nany point, but instead as a _single_, _pre-validated_, type-safe data structure\nthat is passed as the input of our program's entry point. It tracks the _source_\nof each value that ends up in the final config, so where a parameter is set is\nnever a mystery.\n\n\u003cimg alt=\"after configliere\" src=\"images/configliere-after.svg\" height=\"500\"\u003e\n\nThis has a profound impact on our program as a whole because it let's us treat\nthe entire process as one function call that takes a single value as its input.\n\n## Summary\n\nConfigiere uses [Standard Schema][standard-schema] to define the static type of\neach configuration parameter as well as to validate that type at runtime. In\nthese examples, we'll use [Zod][zod], but you can use\n[any library that implements the Standard Schema spec][schema-libs].\n\nThis basic example uses configliere to specify the host and port of a \"Hello\nWorld\" server:\n\n```ts\n// server.js\nimport { createServer } from \"node:http\";\nimport { fileExistsSync, readFileSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { Configliere, ObjectInput } from \"configliere\";\n\nexport const configliere = new Configliere({\n  host: {\n    schema: z.string(),\n  },\n  port: {\n    schema: z.number(),\n  },\n});\n\n// read a config file if it exists\nconst objects: ObjectInput[] = [];\nif (fileExistsSync(\"./config.json\")) {\n  objects.push({\n    value: JSON.parse(readFileSync(\"./config.json\")),\n    source: \"./config.json\",\n  });\n}\n\nconst result = configliere.parse({\n  objects,\n  args: process.argv.slice(1),\n  env: process.env,\n});\n\nif (!result.ok) {\n  console.error(result.summary);\n  process.exit(1);\n}\n\nconst server = createServer((_, res) =\u003e {\n  res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n  res.end(\"Hello World\\n\");\n});\n\nserver.listen(config.port, config.host, () =\u003e {\n  console.log(`server listening at ${config.host}:${config.port}`);\n});\n```\n\nThis will allow us to configure our server from the CLI\n\n```\nnode server.js --port 80 --host localhost\n```\n\nBut also using environment variables:\n\n```\nPORT=80 HOST=localhost node server.js\n```\n\nOr a static configuration file:\n\n```\n{\n  \"host\": \"localhost\",\n  \"port\": 80,\n}\n```\n\nThey can also be used in coordination with each other:\n\n```\nHOST=localhost node server.js --port 80\n```\n\nIn all cases however, the values of `host` and `port` proceed through the exact\nsame validation and error reporting process.\n\n## Configuration Sources\n\n### CLI\n\n- boolean values\n- array values\n- printing help\n\n### Environment Variables\n\n- bolean values\n\n### Config Files\n\n- Using typescript for statically typed configuration files.\n\n[standard-schema]: https://standardschema.dev\n[zod]: https://zod.dev\n[schema-libs]: https://standardschema.dev/#what-schema-libraries-implement-the-spec\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthefrontside%2Fconfigliere","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthefrontside%2Fconfigliere","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthefrontside%2Fconfigliere/lists"}