                    (not (:exception compile-data)))
               (binding [env/*compiler* compiler-env
                         cljs.repl/*repl-env* repl-env]
-                (let [modified-sources (sources-modified! @compiler-env last-modified)
-                      namespaces (sources->namespaces-to-reload modified-sources)]
+                (let [namespaces
+                      (if (contains? compile-data :changed-files)
+                        (paths->namespaces-to-reload (:changed-files compile-data))
+                        (->> (sources-modified! @compiler-env last-modified)
+                             (sources->namespaces-to-reload)))]
                   (when-let [warnings (:warnings compile-data)]
                     (handle-warnings warnings))
                   (reload-namespaces namespaces)))

;; building
;; -------------------------------------------------------------

;; TODO should handle case of already having changed files
(let [cljs-build cljs.closure/build]
  (defn build
    ([src opts] (with-redefs [cljs.closure/build build]
                  (cljs-build src opts)))
    ([src opts compiler-env]
     (let [local-data (volatile! {})]
       (binding [cljs.analyzer/*cljs-warning-handlers*
                 (conj cljs.analyzer/*cljs-warning-handlers*

                  (fn [x]
                    (merge (select-keys x [:started])
                           @local-data
                           (cond-> {:finished (System/currentTimeMillis)}
                             (some? changed-files) ;; accept empty list here
                             (assoc :changed-files changed-files)))))
           (vreset! local-data {})
           (catch Throwable e
             (swap! compiler-env
