--- a/js/app/after_build.js	2026-05-28 14:03:04.411110834 +0000
+++ b/js/app/after_build.js	2026-05-28 14:03:32.000852551 +0000
@@ -1,7 +1,7 @@
-import { writeFileSync, copyFileSync } from "fs";
+import { writeFileSync, copyFileSync, cpSync, mkdirSync, readFileSync } from "fs";
 import { resolve, dirname } from "path";
 import { fileURLToPath } from "url";
-import { execSync } from "child_process";
+import { createRequire } from "module";
 
 const __filename = fileURLToPath(import.meta.url);
 const __dirname = dirname(__filename);
@@ -20,8 +20,29 @@
 	)
 );
 
-// Install http-proxy in the build output so it's available at runtime
-execSync("npm install --production", { cwd: out_path, stdio: "inherit" });
+// Vendor http-proxy and its production dependency closure into the build
+// output so it's available at runtime. Upstream runs `npm install --production`
+// here, but the packages are already present in the workspace, so we copy them
+// instead of hitting the network.
+const out_node_modules = resolve(out_path, "node_modules");
+mkdirSync(out_node_modules, { recursive: true });
+
+const copied = new Set();
+function vendor(name, parentRequire) {
+	if (copied.has(name)) return;
+	copied.add(name);
+	const pkgJsonPath = parentRequire.resolve(`${name}/package.json`);
+	cpSync(dirname(pkgJsonPath), resolve(out_node_modules, name), {
+		recursive: true,
+		dereference: true
+	});
+	const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
+	const ownRequire = createRequire(pkgJsonPath);
+	for (const dep of Object.keys(pkgJson.dependencies || {})) {
+		vendor(dep, ownRequire);
+	}
+}
+vendor("http-proxy", createRequire(import.meta.url));
 
 // Replace the adapter-generated index.js with our custom proxy entry point
 copyFileSync(
