diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..5e1e32e
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+HP_ENV=
diff --git a/.gitignore b/.gitignore
index 2dfe775..23d910b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 .qlot
 bin/tailwindcss
 public/style/dist.css
+.env
diff --git a/qlfile b/qlfile
index 5a2c45f..dbef4b0 100644
--- a/qlfile
+++ b/qlfile
@@ -8,4 +8,5 @@ ql clack
 git hsx https://github.com/skyizwhite/hsx.git
 git ningle-fbr https://github.com/skyizwhite/ningle-fbr.git
 git lack-mw https://github.com/skyizwhite/lack-mw.git
-git trivial-backtrace https://github.com/hraban/trivial-backtrace.git
\ No newline at end of file
+git trivial-backtrace https://github.com/hraban/trivial-backtrace.git
+ql cl-dotenv
diff --git a/qlfile.lock b/qlfile.lock
index ac6ecd1..0e4ba1a 100644
--- a/qlfile.lock
+++ b/qlfile.lock
@@ -46,3 +46,7 @@
  (:class qlot/source/git:source-git
   :initargs (:remote-url "https://github.com/hraban/trivial-backtrace.git")
   :version "git-7f90b4a4144775cca0728791e4b92ac2557b07a1"))
+("cl-dotenv" .
+ (:class qlot/source/ql:source-ql
+  :initargs (:%version :latest)
+  :version "ql-2018-10-18"))
diff --git a/src/env.lisp b/src/env.lisp
new file mode 100644
index 0000000..4eec08a
--- /dev/null
+++ b/src/env.lisp
@@ -0,0 +1,14 @@
+(defpackage #:hp/env
+  (:use #:cl)
+  (:import-from #:cl-dotenv
+                #:load-env)
+  (:export #:hp-env))
+(in-package #:hp/env)
+
+(load-env (merge-pathnames "./.env"))
+
+(defmacro env-var (name var)
+  `(defun ,name ()
+     (or (uiop:getenv ,var) "")))
+
+(env-var hp-env "HP_ENV")
diff --git a/src/middlewares/recoverer.lisp b/src/middlewares/recoverer.lisp
index 44079d2..5937889 100644
--- a/src/middlewares/recoverer.lisp
+++ b/src/middlewares/recoverer.lisp
@@ -3,6 +3,8 @@
         #:hsx)
   (:import-from #:trivial-backtrace
                 #:print-backtrace)
+  (:import-from #:hp/env
+                #:hp-env)
   (:export #:*recoverer*))
 (in-package #:hp/middlewares/recoverer)
 
@@ -14,7 +16,7 @@
      (body
        (main
          (h1 "500 Internal Server Error")
-         (when (string= (uiop:getenv "HP_ENV") "dev")
+         (when (string= (hp-env) "dev")
            (hsx
             (pre
               (code (print-backtrace condition :output nil))))))))))
diff --git a/src/renderer.lisp b/src/renderer.lisp
index b225868..17d1bd4 100644
--- a/src/renderer.lisp
+++ b/src/renderer.lisp
@@ -4,11 +4,15 @@
         #:trivia)
   (:import-from :jingle)
   (:import-from #:hsx/element
-                #:element))
+                #:element)
+  (:import-from #:hp/env
+                #:hp-env))
 (in-package #:hp/renderer)
 
 (defun bust-cache (url)
-  (format nil "~a?v=~a" url (get-universal-time)))
+  (format nil "~a?v=~a" url (if (string= (hp-env) "dev")
+                                (get-universal-time)
+                                #.(get-universal-time))))
 
 (defparameter *metadata-template*
   (list :title (lambda (title)
@@ -70,7 +74,7 @@
 
 (defmethod jingle:process-response ((app jingle:app) result)
   (jingle:set-response-header :content-type "text/html; charset=utf-8")
-  (when (string= (uiop:getenv "HP_ENV") "dev")
+  (when (string= (hp-env) "dev")
     (jingle:set-response-header :cache-control "no-store, no-cache, must-revalidate")
     (jingle:set-response-header :pragma "no-cache")
     (jingle:set-response-header :expires "0"))