       (spit file (compile-client-js opts)))
     file))
 
-(defn repl-env [& {:as opts}]
+(defn- provides-and-requires
+  "Return a flat list of all provided and required namespaces from a
+  sequence of IJavaScripts."
+  [deps]
+  (flatten (mapcat (juxt :provides :requires) deps)))
+
+(defn- always-preload
+  "Return a list of all namespaces which are always loaded into the browser
+  when using a browser-connected REPL."
+  []
+  (let [cljs (provides-and-requires (cljsc/cljs-dependencies {} ["clojure.browser.repl"]))
+        goog (provides-and-requires (cljsc/js-dependencies {} cljs))]
+    (disj (set (concat cljs goog)) nil)))
+
+(defn repl-env
+  "Create a browser-connected REPL environment.
+
+  Options:
+
+  port:           The port on which the REPL server will run. Defaults to 9000.
+  working-dir:    The directory where the compiled REPL client JavaScript will
+                  be stored. Defaults to \".repl\".
+  serve-static:   Should the REPL server attempt to serve static content?
+                  Defaults to true.
+  static-dir:     List of directories to search for static content. Defaults to
+                  [\".\" \"out/\"].
+  preloaded-libs: List of namespaces that should not be sent from the REPL server
+                  to the browser. This may be required if the browser is already
+                  loading code and reloading it would cause a problem.
+  optimizations:  The level of optimization to use when compiling the client
+                  end of the REPL. Defaults to :simple.
+  "
+  [& {:as opts}]
   (let [opts (merge {:port          9000
                      :optimizations :simple
                      :working-dir   ".repl"
                      :serve-static  true
-                     :static-dir    ["." "out/"]}
+                     :static-dir    ["." "out/"]
+                     :preloaded-libs   []}
                     opts)]
-    (do (swap! server-state
+    (do (reset! preloaded-libs (set (concat (always-preload) (map str (:preloaded-libs opts)))))
+        (reset! loaded-libs @preloaded-libs)
+        (swap! server-state
                (fn [old] (assoc old :client-js
                                (future (create-client-js-file
                                         opts

                             :client-js nil}))

(def loaded-libs (atom #{}))

(defn- connection
  "Promise to return a connection when one is available. If a

(defmulti handle-post (fn [_ m] (:type m)))

(defmethod handle-post :ready [conn _]
  (do (reset! loaded-libs @preloaded-libs)
      (send ordering (fn [_] {:expecting nil :fns {}}))
      (send-for-eval conn
                     (cljsc/-compile
