<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="288707" data-post-id="288707">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="christhekeele" data-post="19" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<p>This is definitely something I want to think about a little later, but definitely something I want to think about more!</p>
</blockquote>
</aside>
<p>It’s not something that’s purified, just some thoughts, plus I might start working sooner than I think and never get around to it, or I might do that plus improve my health and do it very soon… absolutely nothing is clear yet.</p>
<p>But yep, I’d like to think some more about it as well. It’s very important to clear up the value proposition before coding.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="288707" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-288707" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="288707"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="289563" data-post-id="289563">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="cmo" data-post="11" data-topic="55888" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cmo/48/19618_2.png" class="avatar"> cmo:</div>
<blockquote>
<p>If you’re concerned about ETS being slow, have you considered using <code>persistent_term</code>?</p>
</blockquote>
</aside>
<p>Having extracted out the initial library and having done some testing, <code>persistent_term</code> is clearly superior for this usecase, compared to my prior <code>:ets</code> solution; both in speed but also simplicity of implementation. I’m grateful to you reminding me about it early on in dev!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="289563" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-289563" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="289563"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="291744" data-post-id="291744">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="D4no0" data-post="4" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/d4no0/48/33624_2.png" class="avatar"> D4no0:</div>
<blockquote>
<p>My only 5 cents is that I think it would be wise to make this configuration type as separate as possible from the classic elixir configuration, as to not introduce more complexity into the runtime and compile-time configuration bucket.</p>
</blockquote>
</aside>
<p>After some development, I’m interested in your thoughts with my prototype API. Today it looks akin to:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># config/config.exs

config :runtime, values: [
  SIGNING_SALT: :string,
  DATABASE_URL: :uri,
  DATABASE_POOL: {:integer, min: 1, max: 100}
]

config :runtime, sources: [
  json: [file: "priv/config.json"],
  exs: [file: "priv/config.exs"],
  dotenv: [file: "priv/config.env"],
  env: []
]
</code></pre>
<p>While I’d love to distance myself even further from the <code>config/*.exs</code> world, having the library know these things in advance at compile-time lets me make very strong guarantees—for example:</p>
<ul>
<li>generating compile-time warnings/errors on typo’d keys
<ul>
<li><em>ie.</em> <code>Runtime.Config.get(:DATABAS_URL)</code></li>
</ul>
</li>
<li>meta-programming clauses with typespecs for specific keys
<ul>
<li><em>ie.</em> letting dialyzer know that  <code>Runtime.Config.get(:DATABASE_URL)</code> will always return a <code>%URI{}</code> struct and contrary usage should emit a warning</li>
</ul>
</li>
</ul>
<p>This API is <code>Keyword</code> based, so plays well with <code>Config</code>’s deep-merging strategy. This means theoretically you could still do stuff like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># config/dev.exs
config :runtime, values: [
  DATABASE_URL: [
    type: :uri,
    required: false,
    default: {:value, "http://localhost:5432/my_app_dev"}
  ]
]
# config/prod.exs
config :runtime, values: [
  DATABASE_URL: [type: :uri, required: true]
]
</code></pre>
<p>or:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># config/dev.exs
config :runtime, sources: [json: [file: "priv/config/dev.json"]]
# config/prod.exs
config :runtime, sources: [json: [file: "priv/config/prod.json"]]
</code></pre>
<p>However, the library would generally discourage such an approach, in favor of a more robust and consolidated “context” DSL. The above examples can be written as:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># config/config.exs

config :runtime, values: [
  DATABASE_URL: [
    type: :uri,
    required: [in: :prod],
    default: [in: [dev: {:value, "http://localhost:5432/my_app_dev"}]]
  ]
]

config :runtime, sources: [
  json: [file: "priv/config/dev.json", in: :dev],
  json: [file: "priv/config/prod.json", in: :prod]
]
</code></pre>
<p>The current context DSL further supports things like specifying that a value is required to have been provided in contexts:</p>
<ul>
<li><code>at: :compile_time | :boot_time | :runtime</code></li>
<li><code>in: [:list, :of, :mix, :envs]</code>,</li>
<li><code>for: [:list, :of, :mix, :targets]</code></li>
</ul>
<p>in any permutation. Similarly for default values, when sources are loaded, and if a source is required to exist <code>at:</code> a certain time <code>in:</code> a certain env <code>for:</code> a certain target.</p>
<p>Thoughts? As far as I can tell, this DSL pretty much allows all compile-time config that actually impacts how a project’s dependencies generate source code to be provided exclusively by traditional <code>config/*.exs</code> mechanisms, and have all other current runtime-config usecases to be described by two single entries for <code>config :runtime</code>. This lets all actual runtime values live outside the <code>config/*.exs</code> world entirely, removing the need for any <code>config/runtime.exs</code> stuff, while preserving compile-time goodies furnished by the library itself.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291744" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-291744" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291744"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="291746" data-post-id="291746">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="D4no0" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/D4no0/120/33624_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  D4no0
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="christhekeele" data-post="24" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<pre data-code-wrap="elixir"><code class="lang-elixir">config :runtime, values: [
  SIGNING_SALT: :string,
  DATABASE_URL: :uri,
  DATABASE_POOL: {:integer, min: 1, max: 100}
]
</code></pre>
</blockquote>
</aside>
<p>Maybe it would be smarter to define a separate file like <code>config_spec.exs</code> and define all constraints there and just import it in your <code>config.exs</code>, in addition to this I’m not sure if you can, but I would definitely avoid using the <code>config</code> macro, since it is unclear whether you are defining a config value or a specification.</p>
<aside class="quote no-group" data-username="christhekeele" data-post="24" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<p>As far as I can tell, this DSL pretty much allows all compile-time config that actually impacts how a project’s dependencies generate source code to be provided exclusively by traditional <code>config/*.exs</code> mechanisms, and have all other current runtime-config usecases to be described by two single entries for <code>config :runtime</code></p>
</blockquote>
</aside>
<p>This is a bad thing in my opinion. I like elixir config because it is crystal clear how it works, all the base configs are evaluated at compile-time (this includes reading from local resources at compile-time) and runtime always loads at boot, with the system you are introducing, people should be a aware of possible limitations/quirks of your configuration lifecycle, witch introduces a lot of complexity into the configuration, witch is something I personally hate having to deal in other languages.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291746" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-291746" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291746"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="291747" data-post-id="291747">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="swarmcommerce" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/swarmcommerce/120/22378_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  swarmcommerce
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/christhekeele" rel="nofollow">@christhekeele</a></p>
<p>I do like <a class="mention" href="/u/d4no0" rel="nofollow">@D4no0</a> 's suggestion here of keeping the config’s semantically separate, with naming along the lines of <code>config_spec.exs</code> which I think is quite an aptly named file.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291747" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-291747" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291747"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="291749" data-post-id="291749">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="D4no0" data-post="25" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/d4no0/48/33624_2.png" class="avatar"> D4no0:</div>
<blockquote>
<p>Maybe it would be smarter to define a separate file like <code>config_spec.exs</code> and define all constraints there and just import it in your <code>config.exs</code>, in addition to this I’m not sure if you can, but I would definitely avoid using the <code>config</code> macro, since it is unclear whether you are defining a config value or a specification.</p>
</blockquote>
</aside>
<p>I’ll agree this is pain point; but mostly one of nomenclature.</p>
<p>Internally all the items in this list get built into something I’m calling a <code>Runtime.Configuration.Specification</code>.</p>
<p>Initially I tinkered with something like <code>config :runtime_config, specifications: [...], sources: [...]</code> as well, but that felt even more distanced from the fact that at some point we are producing a strongly-typed runtime <code>:value</code>. I’m wondering if you feel like that reads better, though.</p>
<p>I do feel like introducing new files like <code>config_spec.exs</code> makes things even more confusing in the <code>config/config.exs</code>  file-naming story. Naming the <code>:otp_app</code> specifically <code>:runtime</code> and sourcing specifications inline via <code>config, :runtime, values: [...]</code> felt like a nice approach that reads better if you imagine a world where all runtime configuration is specified thusly, but I see where you’re coming from.</p>
<hr>
<aside class="quote no-group" data-username="D4no0" data-post="25" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/d4no0/48/33624_2.png" class="avatar"> D4no0:</div>
<blockquote>
<p>I like elixir config because it is crystal clear how it works, all the base configs are evaluated at compile-time (this includes reading from local resources at compile-time) and runtime always loads at boot, with the system you are introducing, people should be a aware of possible limitations/quirks of your configuration lifecycle, witch introduces a lot of complexity into the configuration, witch is something I personally hate having to deal in other languages.</p>
</blockquote>
</aside>
<p>I do have to disagree here, I think it’s really unclear. We see posts to this effect all the time, even with experienced devs, in these forums (<a href="https://forum.elixirforum.com/t/config-exs-and-system-get-env-2-are-values-actually-read-at-runtime/56481" rel="nofollow">random recent example from a search</a>) and especially from newcomers on <a href="https://stackoverflow.com/search?q=%5Belixir%5D+configuration" rel="noopener nofollow ugc">stack overflow</a>. That’s been a major motivation to me to ideate an alternate approach, whether or not it catches on.</p>
<p>I do feel like a <em><strong>LOT</strong></em> of pain could have been saved early on by simple renaming:</p>
<ul>
<li><code>config/config.exs</code> → <code>config/compile_time.exs</code></li>
<li><code>config/runtime.exs</code> → <code>config/boot_time.exs</code></li>
</ul>
<p>making it properly clear when these things get loaded, and that none of these configuration sources contain true, runtime-loadable, runtime-modifiable solutions (without <code>System.get_env</code>-deferring hacks and ultimately storing them in distributed-erlang-friendly datastores to support runtime modifications).</p>
<p>If I’m working within these constraints to build such a runtime-friendly system, I have to work within these historical decisions today, since Elixir 2.0 may never be published to support this kind of change. Having this be calls to <code>config :runtime</code> in a single <code>config/config.exs</code> file and a robust context DSL feels like the best way to do this to me.</p>
<hr>
<p>Indeed, in my applications today, I tend to:</p>
<ul>
<li>set <code>config_path: "config/compile_time.exs"</code> in my <code>mix.exs</code></li>
<li>set <code>runtime_config_path: "config/boot_time.exs"</code> in my <code>mix.exs</code></li>
<li>delete <code>import_config "#{config_env()}.exs"</code> in my <code>config/compile_time.exs</code>, in favor of:
<ul>
<li><code>case config_env() do...</code> in my <code>config/compile_time.exs</code></li>
<li><code>case config_target() do...</code> in my <code>config/boot_time.exs</code>, ex for nerves projects</li>
</ul>
</li>
<li>handle actual runtime configuration loading and updates in my <code>Application</code> callbacks with distributed <code>Phoenix.PubSub</code> and clever supervision trees</li>
</ul>
<p>This is fine for myself, but spreads things even further around my codebase against convention, with less ability to reason about a project’s configuration in a single place.</p>
<p>Empowering devs to reason about this with a single library and a single declarative <code>config/config.exs</code> with the occasional <code>case config_env() do...</code> thrown in there for actual compile-time-required changes to how dependencies generate code in different envs is the major motivation of this project.</p>
<p>I also personally hate dealing with this complexity in other languages, which is why I’m trying to design something that can manage that complexity even at runtime-modification levels, but with sane defaults for the standard project requirements to support lightweight specification in common usage, that can all fit within a single <code>config/config.exs</code> file.</p>
<hr>
<p>I know I’m refuting a lot of your feedback here, but I do want to make it clear that I really appreciate it, and it is indeed informing me about how this might be received even if I double down on my current approach. I think I may take a walk around the block for a bit, implement the distributed-system support and install it into my existing projects, and open-source things before I try to rethink if I want to handle the declarative configuration specification approach differently with your feedback in mind, armed with more context and real-world perspectives.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291749" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-291749" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291749"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="291750" data-post-id="291750">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="D4no0" data-post="25" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/d4no0/48/33624_2.png" class="avatar"> D4no0:</div>
<blockquote>
<p>In addition to this I’m not sure if you can, but I would definitely avoid using the <code>config</code> macro, since it is unclear whether you are defining a config value or a specification.</p>
</blockquote>
</aside>
<p>To dive into this deeper, I <em>could</em> avoid it, but that would prohibit me from doing my clever little compile-time guarantees as mentioned in my last post:</p>
<aside class="quote no-group" data-username="christhekeele" data-post="24" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<ul>
<li>generating compile-time warnings/errors on typo’d keys
<ul>
<li><em>ie.</em> <code>Runtime.Config.get(:DATABAS_URL)</code></li>
</ul>
</li>
<li>meta-programming clauses with typespecs for specific keys
<ul>
<li><em>ie.</em> letting dialyzer know that <code>Runtime.Config.get(:DATABASE_URL)</code> will always return a <code>%URI{}</code> struct and contrary usage should emit a warning</li>
</ul>
</li>
</ul>
</blockquote>
</aside>
<p>Pretty much the only window of time I have to modify how <code>Runtime</code> generates functions in different contexts pre-compilation based on the user’s input is by reading from <code>Application.get_all_env(:runtime)</code>, so I’d have to say goodbye to some features without it.</p>
<p>Doing this via <code>config</code> has introduced some <em>major</em> pains in supporting user-defined custom <code>Runtime.Configuration.Type</code> and <code>Runtime.Configuration.Source</code> structs, since they aren’t yet available at <code>Runtime</code>’s compile-time, so abandoning it is not off the table. But I waited until I had a work-around for this and proven the concept before re-soliciting your opinions on the <code>config</code> soultion.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291750" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-291750" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291750"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="291751" data-post-id="291751">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="D4no0" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/D4no0/120/33624_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  D4no0
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="christhekeele" data-post="27" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<p>I do have to disagree here, I think it’s really unclear. We see posts to this effect all the time, even with experienced devs, in these forums (<a href="https://forum.elixirforum.com/t/config-exs-and-system-get-env-2-are-values-actually-read-at-runtime/56481" rel="nofollow">random recent example from a search</a>) and especially from newcomers on <a href="https://stackoverflow.com/search?q=%5Belixir%5D+configuration" rel="noopener nofollow ugc">stack overflow</a>. That’s been a major motivation to me to ideate an alternate approach, whether or not it catches on.</p>
</blockquote>
</aside>
<p>The actual complexity is the config impact with the metaprogramming system, it is true that it is rather peculiar that elixir was supporting only compile-time config back in the day, however your approach does not abstract it away, rather it tries to blend it in, adding another layer of possible complexity. It is also imperative that you should take into consideration why elixir design team decided to go with the <code>runtime.exs</code> approach, even though they had the possibility to make an implementation like yours. We all have our vision of how a system should work, based on what we worked/saw previously, however the philosophy of the language should be taken into consideration, otherwise we might end up with an abomination of language and ecosystem like javascript.</p>
<aside class="quote no-group" data-username="christhekeele" data-post="27" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<p>I do feel like a <em><strong>LOT</strong></em> of pain could have been saved early on by simple renaming:</p>
<ul>
<li><code>config/config.exs</code> → <code>config/compile_time.exs</code></li>
<li><code>config/runtime.exs</code> → <code>config/boot_time.exs</code></li>
</ul>
</blockquote>
</aside>
<p>It is true that the default compile-time config could be somehow marked better, however the <code>runtime.exs</code> is named perfect, the config is loaded at runtime, the fact that it is loaded when the server boots is just a implementation detail. Back in the day, credo helped me a lot to understand clearly how configs should be used correctly, because it would throw an error when using <code>Application.get_env</code> on compile-time configs and force you to use <code>Application.compile_env</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291751" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-291751" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291751"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #28"></div>
  </section>
</div>
    <div class="postbit" id="291752" data-post-id="291752">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="christhekeele" data-post="28" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/48/1039_2.png" class="avatar"> christhekeele:</div>
<blockquote>
<p>Pretty much the only window of time I have to modify how <code>Runtime</code> generates functions in different contexts pre-compilation based on the user’s input is by reading from <code>Application.get_all_env(:runtime)</code></p>
</blockquote>
</aside>
<p>(I am not willing to describe to you how atrocious the <code>Runtime.CompileTime</code> module looks yet. <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20">)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291752" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-291752" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291752"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #29"></div>
  </section>
</div>
    <div class="postbit" id="291753" data-post-id="291753">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="christhekeele" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/christhekeele/120/1039_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  christhekeele
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="D4no0" data-post="29" data-topic="55888">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/d4no0/48/33624_2.png" class="avatar"> D4no0:</div>
<blockquote>
<p>It is also imperative that you should take into consideration why elixir design team decided to go with the <code>runtime.exs</code> approach, even though they had the possibility to make an implementation like yours.</p>
</blockquote>
</aside>
<p>I agree with this. I followed the discussion on the core mailing list and other forums while it was being developed, and I do think I have an intuition — they were trying to improve the compile-time-only issues of the time, to support boot-time configuration from ENV vars. Supporting runtime-<em>modifiable configuration</em> was way out of scope, and does belong in its own library. What upsets me is that trying develop such a library is immediately confusing by the name of <code>runtime.exs</code> instead of <code>boot-time.exs</code>, I wish I’d agitated more about the decision back then…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="291753" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/library-for-runtime-application-configuration-interested/55888/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-291753" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="291753"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/55888/load_more?page=4">Load more posts (8 remaining)</a>
</div></template></turbo-stream>