                     (and build-worker? default? (= :browser runtime))
                     (update :entries shared/prepend '[shadow.cljs.devtools.client.browser])
 
+                    (and build-worker? default? (= :custom runtime) (:client-ns devtools))
+                    (update :entries shared/prepend [(:client-ns devtools)])
+
                     (and (seq preloads) (= :dev mode))
                     (update :entries shared/prepend preloads)
 

(defn str-prepend [x y]
  (str y x))

(s/def ::runtime #{:node :browser :react-native})

(s/def ::exports
  (s/map-of simple-ident? qualified-symbol? :min-count 1))

    ::build/keys [config]
    :as state}]

  (->> ["globalThis.CLOSURE_DEFINES = " (output/closure-defines-json state) ";"
        "globalThis.CLOSURE_NO_DEPS = true;"
        ;; the global must be overriden in goog/base.js since it contains some
        ;; goog.define(...) which would otherwise be exported to "this"
        ;; but we need it on $CLJS
        (-> (data/get-output! state {:resource-id output/goog-base-id})
            (get :js)
            ;; FIXME: this is using the compiled variant of goog/base.js
            ;; don't use goog-global-snippet, that is used for uncompiled goog/base.js
            ;; keeping both variants for now until I can make this cleaner
            (str/replace "goog.global = this || self;" "goog.global = globalThis;"))

        "globalThis.goog = goog;"
        "globalThis.shadow$provide = {};"
        "globalThis.shadow_esm_import = function(x) { return import(x.startsWith(\"./\") ? \".\" + x : x); }"
        "let $CLJS = globalThis.$CLJS = globalThis;"
        (slurp (io/resource "shadow/boot/esm.js"))

        (when (seq polyfill-js)
          (str polyfill-js "\n"
               "globalThis.$jscomp = $jscomp;\n"))]
       (remove nil?)
       (str/join "\n")))

(defn flush-dev [{::build/keys [config] :keys [build-modules] :as state}]
  (when-not (seq build-modules)
