{"id":32167950,"url":"https://github.com/alexiob/spellbook","last_synced_at":"2026-02-23T05:01:42.775Z","repository":{"id":57551156,"uuid":"68484005","full_name":"alexiob/spellbook","owner":"alexiob","description":"Elixir library providing dynamic hierarchical configurations loading for your application.","archived":false,"fork":false,"pushed_at":"2019-09-05T11:31:09.000Z","size":60,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-21T15:42:40.491Z","etag":null,"topics":["configuration","configuration-files","elixir","elixir-library"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/alexiob.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-17T23:47:23.000Z","updated_at":"2023-10-30T05:46:49.000Z","dependencies_parsed_at":"2022-09-26T18:41:49.392Z","dependency_job_id":null,"html_url":"https://github.com/alexiob/spellbook","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexiob/spellbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexiob%2Fspellbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexiob%2Fspellbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexiob%2Fspellbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexiob%2Fspellbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexiob","download_url":"https://codeload.github.com/alexiob/spellbook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexiob%2Fspellbook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29738083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T04:51:08.365Z","status":"ssl_error","status_checked_at":"2026-02-23T04:49:15.865Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["configuration","configuration-files","elixir","elixir-library"],"created_at":"2025-10-21T15:41:26.815Z","updated_at":"2026-02-23T05:01:42.731Z","avatar_url":"https://github.com/alexiob.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spellbook\n\n[![Build Status](https://travis-ci.org/alexiob/spellbook.svg?branch=master)](https://travis-ci.org/alexiob/spellbook)\n[![Inline docs](http://inch-ci.org/github/alexiob/spellbook.svg)](http://inch-ci.org/github/alexiob/spellbook)\n[![Hex version](https://img.shields.io/hexpm/v/spellbook.svg)](https://hex.pm/packages/spellbook)\n[![Coverage Status](https://coveralls.io/repos/github/alexiob/spellbook/badge.svg?branch=master)](https://coveralls.io/github/alexiob/spellbook?branch=master)\n[![hex.pm downloads](https://img.shields.io/hexpm/dt/spellbook.svg)](https://hex.pm/packages/spellbook)\n\n## Introduction\n\nSpellbook is an Elixir library providing dynamic hierarchical configurations loading for your application.\nIt is based on the ideas implemented in the Javascript [node-config](https://nodei.co/npm/config/) module.\n\nIt lets you define a set of default parameters, and extend them for different deployment environments (development, staging, production, etc.) or custom needs (client id, hostname, etc.).\n\nConfigurations are stored in default or custom folders containing configuration files and can be overridden and extended by environment variables.\n\nCustom configuration static and dynamic filenames and file formats can be added as needed.\n\n## Installation\n\nAdd Spellbook as a dependency to your `mix.exs` file.\n\n```elixir\ndefp deps do\n  [{:spellbook, \"~\u003e 2.0.3\"}]\nend\n```\n\n## Documentation\n\nThe API reference can be found [here](https://hexdocs.pm/spellbook/api-reference.html).\n\n## Quick Start\n\n### Read the configuration files from the standard `\u003cCWD\u003e/config` folder\n\n```elixir\nconfig = Spellbook.load_config_folder()\n```\n\nUsing `Spellbook.load_config_folder/0` by default will use the following filename templates (in the listed order and if they exist) with the `{SOMETHING}` template variables substituted:\n\n```txt\n\u003cCWD\u003e/config/default.{EXT}\n\u003cCWD\u003e/config/default-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/{ENV}.{EXT}\n\u003cCWD\u003e/config/{ENV}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/{SHORT_HOSTNAME}.{EXT}\n\u003cCWD\u003e/config/{SHORT_HOSTNAME}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/{SHORT_HOSTNAME}-{ENV}.{EXT}\n\u003cCWD\u003e/config/{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/{FULL_HOSTNAME}.{EXT}\n\u003cCWD\u003e/config/{FULL_HOSTNAME}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/{FULL_HOSTNAME}-{ENV}.{EXT}\n\u003cCWD\u003e/config/{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/local.{EXT}\n\u003cCWD\u003e/config/local-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/local-{ENV}.{EXT}\n\u003cCWD\u003e/config/local-{ENV}-{INSTANCE}.{EXT}\n\u003cCWD\u003e/config/custom-env-variables.{EXT}\n```\n\nSpellbook will use the default environment (`{ENV}` = `dev`) and the full hostname of the machine the code gets executed on (`{FULL_HOSTNAME}` = `my-machine.spellbook.domain`). As the other template variables are not defined, the filenames using them are ignored.\nThe resulting filenames searched/merged will be:\n\n```txt\n\u003cCWD\u003e/config/default.json\n\u003cCWD\u003e/config/default.yaml\n\u003cCWD\u003e/config/dev.json\n\u003cCWD\u003e/config/dev.yaml\n\u003cCWD\u003e/config/my-machine.spellbook.domain.json\n\u003cCWD\u003e/config/my-machine.spellbook.domain.yaml\n\u003cCWD\u003e/config/my-machine.spellbook.domain-dev.json\n\u003cCWD\u003e/config/my-machine.spellbook.domain-dev.yaml\n\u003cCWD\u003e/config/local.json\n\u003cCWD\u003e/config/local.yaml\n\u003cCWD\u003e/config/local-dev.json\n\u003cCWD\u003e/config/local-dev.yaml\n\u003cCWD\u003e/config/custom-env-variables.json\n\u003cCWD\u003e/config/custom-env-variables.yaml\n```\n\nBy default Spellbook supports JSON and YAML file formats.\n\n### Read brand's configuration from a specific folder with custom settings for a specific client\n\n```elixir\nconfig = Spellbook.default_config()\n|\u003e Spellbook.add_filename_format(\"clients/#{brand}.#{ext}\")\n|\u003e Spellbook.load_config(\n  folder: \"./test/support/brand\",\n  config_filename: \"brand-conf\",\n  vars: [instance: \"job-processor\", brand: \"elixir\", env: \"prod\", short_hostname: \"worker\"]\n)\n```\n\nHere we specify a specific folder were to look for the configuration files (with the `folder` option), a custom configuration file name (with the `config_filename` option). The `vars` configuration field is used to define the variable values used in the filename templates.\n\nThe `Spellbook.default_config/0` function (and the `Spellbook.load_config/0` one as well) configures the Spellbook to search for the following file templates:\n\n```txt\n./test/support/brand/{CONFIG\\_FILENAME}.{EXT}\n./test/support/brand/{CONFIG\\_FILENAME}-{INSTANCE}.{EXT}\n./test/support/brand/{CONFIG\\_FILENAME}-{ENV}.{EXT}\n./test/support/brand/{CONFIG\\_FILENAME}-{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}\n./test/support/brand/{CONFIG\\_FILENAME}-{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}\n./test/support/brand/clients/{BRAND}.{EXT}\n./test/support/brand/custom-env-variables.{EXT}\n```\n\nIn this case the searched/merged files will be:\n\n```txt\n./test/support/brand/brand-conf.json\n./test/support/brand/brand-conf.yaml\n./test/support/brand/brand-conf-job-processor.json\n./test/support/brand/brand-conf-job-processor.yaml\n./test/support/brand/brand-conf-prod.json\n./test/support/brand/brand-conf-prod.yaml\n./test/support/brand/brand-conf-worker-prod-job-processor.json\n./test/support/brand/brand-conf-worker-prod-job-processor.yaml\n./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.json\n./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.yaml\n./test/support/brand/clients/elixir.json\n./test/support/brand/clients/elixir.yaml\n./test/support/brand/custom-env-variables.json\n./test/support/brand/custom-env-variables.yaml\n```\n\n### Get a value out of a Spellbook configuration\n\nA configuration is just a Map.\n\n```elixir\niex\u003e config = Spellbook.load_config_folder()\n%{ \"some\" =\u003e %{ \"value\" =\u003e %{ \"from\" =\u003e %{ \"config\" =\u003e \"a value\" }}}}\niex\u003e is_map(config) == true\ntrue\n```\n\nYou can access the configuration values using the standard language features\n\n```elixir\niex\u003e value = config[\"some\"][\"value\"][\"from\"][\"config\"]\n\"a value\"\n```\n\nor using the `Spellbook.get` method that supports dot notation to access elements deep down the configuration structure:\n\n```elixir\niex\u003e value = Spellbook.get(config, \"some.value.from.config\")\n\"a value\"\n```\n\n### Use environment variables in configuration files\n\nSome situations rely heavily on environment variables to configure secrets and settings best left out of a codebase. Spellbook lets you use map the environment variable names into your configuration structure using a `custom-env-variables.{EXT}` file:\n\n```json\n{\n  \"database\": {\n    \"username\": \"DB_USERNAME\",\n    \"password\": \"DB_PASSWORD\"\n  }\n}\n```\n\nIf the `DB_USERNAME` and `DB_PASSWORD` environment variable exist, they would override the values for `database.username` and `database.password` in the configuration.\n\nA special syntax allows environment variables typecast as well:\n\n```json\n{\n  \"database\": {\n    \"port\": \"DB_PORT.integer\"\n  }\n}\n```\n\nWill convert the \"DB_PORT\" environment variable into an integer. Supported typecasts are:\n\n- \"integer\" (also \"int\", \"i\")\n- \"float\" (also \"f\")\n- \"boolean\" (also \"bool\", \"b\"): converts \"false\", \"f\", \"0\" to false, everything else to true.\n\nCustom environment variables have precedence and override all configuration files, including `local.json`.\n\n## License\n\nSpellbook is provided under the [MIT license](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexiob%2Fspellbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexiob%2Fspellbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexiob%2Fspellbook/lists"}