What is an idiomatic way to handle application configuration in clojure?

So far I use this environment:

;; config.clj
{:k1 "v1"
 :k2 2}

;; core.clj
(defn config []
  (let [content (slurp "config.clj")]
    (binding [*read-eval* false]
      (read-string content))))

(defn -main []
  (let [config (config)]
    ...))

Which has many downside:

  • The path to config.clj might not always be resolved correctly
  • No clear way to structure config sections for used libraries/frameworks
  • Not globally accessible (@app/config) (which of course, can be seen as a good functional style way, but makes access to config across source file tedious.

Bigger open-source projects like storm seem to use YAML instead of Clojure and make the config accessible globally via a bit ugly hack: (eval ``(def ~(symbol new-name) (. Config ~(symbol name)))).

Edit
Report