Documentation Troubleshooting
Troubleshooting#
Desktop runtime: Bun. Android and iOS are deferred. See BUN-MIGRATION.md for the current architecture and changes from the historical QuickJS runtime.
Start with the exact command that fails and keep the first Blitsen error. The CLI names the build stage and exits non-zero instead of continuing with a partial artifact.
missing application directory#
Pass a directory containing index.html:
blitsen distOr add a blitsen object with an output directory to package.json and run without a directory.
Blitsen does not guess a dist name.
missing or unreadable entrypoint#
The directory exists but does not contain a readable index.html. Check the build output rather
than the project root:
npm run build
ls dist/index.html
blitsen distSource files or bare imports are refused#
Messages naming .tsx, .jsx, .vue, .svelte or a bare import mean Blitsen received source
instead of browser-ready output. Build first:
npm run build
blitsen distFor development source, point Blitsen at the development server rather than its source directory:
blitsen http://localhost:5173The development-server window is blank#
Verify the URL in a browser or with another HTTP client and check the server terminal. Blitsen does not start the server for you. Bind it to an address reachable from the process, then retry the exact HTTP or HTTPS URL.
If the page loads but hot reload does not connect, configure the server's explicit HMR host and
client port. Vite projects use server.hmr.host and server.hmr.clientPort.
No window appears for a moment after launch#
This is deliberate. A window is created hidden and mapped only after the first complete frame has been painted, so the application is never seen as an empty or half-drawn rectangle. The wait is whatever it takes to load the document's critical subresources — stylesheets and web fonts — and to bring up the GPU surface, which is slowest on a cold start.
A wait long enough to look like a hang usually means a stylesheet or font is still outstanding. Check the paths in the built output, and remember that a remote subresource is not fetched: it is answered empty rather than waited on. Against a development-server URL, look at the server terminal for requests that never complete.
Doctor reports warnings but exits successfully#
Warnings describe behavior that may degrade or may be protected by feature detection. Doctor does not prove that a warning is harmless. Find the call site, confirm whether it executes, add a fallback where possible and test the built application in Blitsen.
Doctor errors block export. --accept-errors exists for an explicitly reviewed exception, but it
does not implement the missing feature.
A local asset is missing from the export#
The collector starts at index.html. If JavaScript computes a filename at runtime, include it:
blitsen build dist --include 'locales/**'Use relative URLs and check the build's omitted-file report. For side-loaded assets, keep the
<output>.assets/ directory beside the executable.
An image, stylesheet or script URL works in a browser only#
Prefer output-relative URLs and configure the bundler with a relative base. Blitsen rewrites common server-root paths in HTML and CSS, but cannot safely rewrite strings assembled by JavaScript. Remote scripts and modules are deliberately not fetched by the runtime.
output already exists#
Choose a different --out path or use --force when replacing the existing artifact is intended:
blitsen build dist --out MyApp --forcePackaging may create several related outputs, such as a Linux .desktop file, a Windows manifest
or a macOS .app; an existing companion can also trigger this refusal.
The target runtime is missing or mismatched#
Reinstall the global CLI with its optional dependencies enabled:
npm install -g blitsenThe CLI and native runtime must have exactly the same version. Do not independently update an
@blitsen/<target> package.
For an exact project-local installation, use npm install -D --save-exact blitsen instead and
keep the lockfile intact.
A cross-target build may need registry/network access to download the target runtime. If the cache
is damaged, remove only the version/target entry reported by the error or set BLITSEN_CACHE_DIR
to a new cache directory; do not modify application output to work around it.
An export carrying a .node addon asks for Bun#
An application with a Node-API addon is linked into the Bun-based host, and that link step is
Bun.build, which only Bun can run. Re-run the same build command with bun on PATH, or remove
the addon — an application without one links Blitsen's own runtime, which needs nothing beyond this
package. See Packaging.
Linux fails to load a shared library#
Published Linux runtimes require glibc 2.35 or newer plus ALSA, OpenSSL 3, fontconfig and the active X11 or Wayland display libraries. Install the missing system package using the distribution's package manager. Headless containers also need a display environment and are not representative of a user desktop.
MALLOC_ARENA_MAX and GLIBC_TUNABLES on Linux#
On Linux glibc targets the runtime limits the allocator to two malloc arenas — mallopt(M_ARENA_MAX, 2),
applied before any thread starts — because per-thread arenas otherwise multiply idle heap in a
process with many threads. It applies that default only when neither MALLOC_ARENA_MAX nor a
GLIBC_TUNABLES entry for glibc.malloc.arena_max is set; set either and your value is left in
force untouched.
WGPU_BACKEND appears in the environment, or only one Vulkan driver is loaded#
On Linux the runtime sets WGPU_BACKEND=vulkan before graphics initialization when the variable is
unset, so wgpu brings up one backend rather than every backend it was compiled with. When Vulkan is
in use, no Vulkan loader override variables are set, and the machine exposes exactly one known DRM
render driver, it also sets VK_LOADER_DRIVERS_SELECT to that driver's ICDs so the loader does not
open every installed one. A value you set for any of these variables is respected and never
replaced; hybrid or unrecognized graphics keep full driver discovery.
A native API is undefined#
Support varies by version and target. Feature-detect the member and grade the intended target:
blitsen doctor dist --target win32-x64Dialogs are available on Linux, macOS and Windows; the single-instance lock uses a Unix socket or Windows named pipe; the app, window, dialog, clipboard, tray and menu native modules are absent on Android. See Native APIs.
macOS notifications need an application bundle identity#
macOS grants notification permission to an application identity, and a development run is an interpreter executing a script, so it has none. Give the development host one of its own:
blitsen --dev-bundleThat builds a signed development .app around the interpreter and re-runs the same command inside
it. Nothing is impersonated: the identifier is com.blitsen.dev.<name> unless --bundle-id names
another, so a permission granted here is not one granted to the application you export. If
codesign rejects the ad-hoc signature — a host binary carrying entitlements is the usual reason —
pass your own command with --sign. See Packaging.
A window or dialog method says the window is unavailable#
Call window-dependent APIs from the load event or later. Document scripts can run before the
native window exists:
import windowApi from "blitsen/window";
addEventListener("load", () => {
windowApi.setSize?.(1024, 720);
});Data disappears after restart#
localStorage persists automatically. If expected data is absent, check whether the development
directory moved or the proxy server's origin/port changed: both intentionally select a different
application namespace. sessionStorage is expected to reset with the JavaScript realm.
A cross-built application is blocked by the OS#
Cross-built artifacts are unsigned unless a suitable signing service was invoked. Sign on the target platform (or through a supported external service), then complete notarization or reputation requirements for that OS. The published Blitsen runtime itself is unsigned.
Android build tools are not found#
Blitsen does not install Rust, the Android SDK/NDK, cargo-ndk, libclang or a JDK. Install those
tools and make their normal environment variables/commands visible. The Android crate must also be
available through the checkout or BLITSEN_ANDROID_CRATE.
Get more diagnostic detail#
- Run
blitsen --versionand record the target OS/architecture. - Run
blitsen doctor dist --jsonand keep the complete report. - Keep the full build output, including the numbered stage where it stopped.
- Reduce the failure to a static
index.htmland its reachable assets if possible. - Search or open an issue in the Blitsen repository with the reproduction, expected result and actual output.