Development and reload
Native server, Vite mode, actual compilation, routes, and Astro shell behavior.
See versions, changes and requirements in Framework 4.0 and CLI 1.2.
Starting the server
wu dev --port 3200 --no-open
The default mode is native. It opens an HTTP listener on 127.0.0.1 and serves the shell and microapps under the same origin. This version’s parser does not offer a --host flag.
| Option | Effect |
|---|---|
--port <n>, -p <n> |
HTTP port in native mode |
--native |
Select the Zig server; this is the default |
--vite |
Select per-app process supervision |
--open, -o |
Request browser opening in native mode |
--no-open |
Prevent opening in native mode |
If --native and --vite appear together, the last selection wins. A port value that cannot be converted to u16 stops being a valid override, so configuration is used. An actual port conflict reports the number and exits with code 1.
What each route serves
| Route | Content |
|---|---|
/ and shell pages |
Shell sources or its Astro/Next build |
/mf-busqueda/src/main.tsx |
Compiled module from that microapp |
/@modules/<specifier> |
npm dependencies resolved for the browser |
/@wu/apps.json |
Development project catalog |
/@wu/client.js |
Injected reload client |
/__wu_ws |
Reload WebSocket channel |
/__wu_hmr |
Alternative SSE channel |
These routes belong to the server, not the application’s business endpoints. Avoid occupying these prefixes with product pages. Resolution uses the app directory to find dependencies and apply .wu-deps.json entries.
On-demand compilation
WU resolves a file when the browser requests it, applies the corresponding compiler, and rewrites imports into loadable URLs. The transformation layer handles npm imports, @/ and ~/ source aliases, and CSS imports.
Vue and Svelte use their compilers; Solid uses its transform and Qwik its optimizer. Angular retains an incremental TypeScript program and esbuild context. TypeScript and JSX require the project’s Node tools; the disabled native JSX transformer from older versions has been removed.
The daemon protocol is multiplexed and a pool compiles modules in parallel. The cache includes compiler versions, lockfiles, .wu-deps.json and tsconfig; the first run after updating recompiles. Logs are in .wu-cache/wu-compiler.log. An error or timeout returns HTTP 500 with an overlay and restarts the daemon when appropriate.
Compiler controls
WU_COMPILE_TIMEOUT_MS sets the compile deadline, 30000 ms by default. WU_COMPILE_WORKERS sets the daemon count, defaulting to min(CPU, 4) with a maximum of 16. WU_COMPILE_PREFETCH=0 disables import precompilation. These variables configure the process that starts wu dev.
Dependencies are prebundled with esbuild in .wu-cache/deps/ and their versioned URLs are immutable. Project files and compiled modules use ETags and 304 revalidation. Static files support HEAD and one byte range (206/416); JSON requested with fetch or import attributes retains its JSON MIME type.
Changes and reload
The watcher includes directories created after startup and uses a numbered event queue. Each module has its own version: an edit invalidates the module and its importers up to the app entry. Unchanged modules keep their instance; a shared change remounts affected apps. Lost events or a server restart trigger a full reload. Local state preservation depends on the framework and the edit.
An Astro or Next shell is a special case: WU serves shell/dist/ or shell/out/. On first startup it attempts a build if index.html is missing. Subsequent changes trigger rebuilding before reload. If the initial build fails, microapps may still be served, but the shell returns 404 until its build command is fixed.
Vite mode
wu dev --vite
This branch creates one process for the shell and one per microapp, using their declared dev_cmd and ports. It adds --port to each command. If an app has a local toolchain, it attempts to run that app’s Vite.
This branch receives configuration, not the port and opening settings calculated for the native server. Therefore, do not expect wu dev --vite --port 3200 to change every port or create native mode’s unified listener. Use Vite mode when you need to check the behavior of the project’s specific toolchain.
Tunnels and environment variables
By default, accepted Host values are localhost, *.localhost and IP literals. CORS and HMR reject foreign origins. For a tunnel, declare the exact hostname without scheme or port; saving the configuration applies the list without restarting. *.example.com accepts subdomains, not the base domain. Avoid wildcards for shared providers.
{ "dev": { "allowedHosts": ["mi-tunel.example.com"] } }
Since 1.1.0, only .env keys prefixed with VITE_ or WU_ reach import.meta.env, in development and native builds. A private key reads as undefined and produces a warning. Migrate only public values: before API_URL / import.meta.env.API_URL; after VITE_API_URL / import.meta.env.VITE_API_URL. Keep secrets in the backend.
File, module, sourcemap and manifest routes check project or package boundaries and symlinks. .env, VCS metadata and keys remain blocked with ?raw, ?import or ?inline; those suffixes do not permit reading private files.
Quick diagnostics
For a blank page, inspect the first failed module request and the browser console. Check wu.json, registration name, grants, and entrypoints as well as the server process. For compilation errors, look for the cause in WU output and the daemon log. If an app is skipped, its directory is missing or duplicated in configuration.
Implementation references
wu-cli/src/commands/dev.zigwu-cli/src/runtime/dev/wu-cli/src/runtime/compile_pool.zigwu-cli/src/runtime/compile_warmup.zigwu-cli/src/runtime/module_graph.zigwu-cli/tests/dev-security.test.cjswu-cli/tests/dev-hmr.test.cjswu-cli/tests/dev-compile-concurrency.test.cjswu-cli/tests/dev-serving.test.cjs