                     (build-compile)))
               )))))
 
-(defn do-idle [{:keys [extra-config-files] :as worker-state}]
+(defn maybe-recover-from-failure
+  [{:keys [package-json-file package-json-lastmod] :as worker-state}]
+  (if-not (and package-json-file package-json-lastmod)
+    worker-state
+    (let [newmod (.lastModified package-json-file)]
+      (if-not (> newmod package-json-lastmod)
+        worker-state
+        (do (log/debug ::package-json-modified)
+            (-> worker-state
+                (dissoc :package-json-file :package-json-lastmod)
+                (cond->
+                  (not (:build-state worker-state))
+                  (build-configure))
+                (build-compile)))))))
+
+(defn do-idle [{:keys [failure-data extra-config-files] :as worker-state}]
   (-> worker-state
       (cond->
         (seq extra-config-files)
-        (maybe-reload-config-files))))
+        (maybe-reload-config-files)
+
+        failure-data
+        (maybe-recover-from-failure)
+        )))

  {:type :repl/error
   :ex e})

(defn build-failure
  [{:keys [build-config] :as worker-state} e]
  (let [{:keys [resource-id resource-ids]} (ex-data e)]
    (-> worker-state
        ;; if any resource was responsible for the build failing we remove it completely
        ;; to ensure that all state is in proper order in the next compile and does not
        ;; contain remnants of the failed compile
        ;; FIXME: should probably check ex-data :tag
        (cond->
          resource-id
          (update :build-state data/remove-source-by-id resource-id)
          resource-ids

            [shadow.build.warnings :as warnings]
            [shadow.build.data :as data]
            [shadow.build.resource :as rc]
            [shadow.build.log :as build-log]
            [clojure.java.io :as io])
  (:import [java.util UUID]))

(defn proc? [x]
