Summary
craft.exe cannot open a window on Windows. CreateCoreWebView2Environment
fails with 0x800401f0 (CO_E_NOTINITIALIZED) because the runtime never
initialises COM on the thread that calls it.
The import table shows it: craft.exe links ole32.dll for exactly one
function, CoTaskMemFree, and imports no CoInitializeEx, CoInitialize or
OleInitialize. That is true of v0.0.100 and of v0.0.140, so it is not a
regression — I could not find a Windows release that does initialise COM.
What happens
⚡ Loading URL in native window: http://127.0.0.1:63854/app
Title: SystemCleaner
Size: 1400x900
[WebView2] Environment creation failed: 0x800401f0
[WebView2] Initialization failed
[2026-10-12T13:04:02Z] ERROR WebView2InitFailedThe process then exits. No window is ever created.
Reproduction
craft.exe http://127.0.0.1:8080/ --title Example --persistent-storage --width 1400 --height 900 --no-devtools- Windows Server 2025 Datacenter, build 26100 (the
windows-latestGitHub Actions runner) - WebView2 Runtime 153.0.4234.48 installed — read from
HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}, so this is not a missing-runtime problem craft.exeandWebView2Loader.dlltaken straight fromcraft-windows-x64.zip, unmodified
Evidence
Parsing the PE import directory of the shipped binaries:
=== v0.0.100
ole32.dll: CoTaskMemFree
KERNEL32.dll: 74 imports
USER32.dll: 22 imports
ntdll.dll: 59 imports
...
=== v0.0.140
ole32.dll: CoTaskMemFree
KERNEL32.dll: 78 imports
USER32.dll: 41 imports
ntdll.dll: 59 imports
...CreateCoreWebView2Environment requires an initialised COM apartment on the
calling thread, and 0x800401f0 is precisely the error for calling it without
one.
(WebView2Loader.dll is absent from the import table because it is loaded with
LoadLibrary/GetProcAddress, which is the normal loader pattern and not
related to this.)
Suggested fix
Call CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED) on the UI thread before
creating the WebView2 environment, and CoUninitialize on the way out.
WebView2 wants an STA. OleInitialize would also do it and additionally sets up
OLE drag-and-drop, which a browser host usually wants.
Also worth a look: the v0.0.90 Windows archive
Unrelated to the above, found while pinning a version.
craft-windows-x64.zip for v0.0.90 contains only craft.exe — no
WebView2Loader.dll, which craft.exe loads by name at runtime. Every release
I checked from v0.0.100 on ships both. A build pinned to v0.0.90 therefore
installs cleanly and then cannot create a webview at all.
Context
Found while building a Windows desktop bundle for
stacksjs/system-cleaner (tracking
issue stacksjs/system-cleaner#23). Everything on our side reaches the runtime
correctly — the loopback agent binds, its health endpoint answers, and
craft.exe receives the URL, title and size shown above — so the failure is
isolated to WebView2 environment creation.
Happy to test a patched build against the same CI job if that is useful.