Documentation Platform support
Platform support#
Blitsen uses Bun on Linux, macOS and Windows, on x64 and arm64. Android and iOS are deferred.
Blitsen is pre-alpha. Platform support means that a runtime is produced, not that every application or operating-system integration behaves identically. Test the exported artifact on each target.
Desktop targets#
| Target | Runtime package | Notes |
|---|---|---|
linux-x64 | @blitsen/linux-x64 | Linux x64 |
linux-arm64 | @blitsen/linux-arm64 | Linux arm64 |
darwin-x64 | @blitsen/darwin-x64 | Intel macOS |
darwin-arm64 | @blitsen/darwin-arm64 | Apple silicon macOS |
win32-x64 | @blitsen/win32-x64 | Windows x64 |
win32-arm64 | @blitsen/win32-arm64 | Windows arm64 |
Only the package matching the install machine is downloaded. A cross-target build fetches the requested runtime separately and stores it in the platform cache.
All desktop targets#
Declarative and runtime tray control—including nested actions, checkboxes, radio groups, accelerators and action/submenu PNGs—notification submission/lifecycle events and focused native input snapshots are available on desktop targets. Checkable tray icons and hidden menu items are not exposed because the native backends do not agree on them.
Root-element fullscreen is available on every desktop through winit. Fullscreen is borderless on the monitor containing the window (primary fallback), never an exclusive video-mode switch. Fullscreen and pointer lock release on Escape, focus loss, surface loss, or target disconnection. Physical multi-monitor placement and grab behavior still require acceptance on Windows and macOS, with fullscreen acceptance separately required on X11 and Wayland.
Gamepad snapshots and connect/disconnect events are available on Linux, macOS and Windows through
the target-gated gilrs backend. No sampling happens at all until the application first touches
the Gamepad API; thereafter controllers are sampled once per application redraw, so an idle
window performs no application-side controller polling and learns about a hot-plug on its next
frame. The backend still owns its platform event worker; the additional 50 ms force-feedback loop
is initialized lazily, on the first nonzero effect rather than for controller-free applications.
Standard dual-rumble is exposed only where the device and driver advertise it. Synthetic tests
cover slot, normalization, event, backend-completion and command semantics; physical hot-plug,
mapping and motor behavior still require representative X11, Wayland, Windows and macOS hardware.
os.batteries reads the machine's own batteries on every desktop target and answers an empty list
where there are none; os.displays and os.idleTime are absent by decision, the monitors being
window.monitors() and idle time having no answer a Wayland client can trust.
Desktop notifications can be updated and closed through their session ID on every desktop target; a Windows toast carries that ID as its own tag, which is what an update replaces and a close removes from the screen and from notification history. Individual notification-server policies still decide how a submitted notification is presented.
blitsen/hid is available on every desktop target, using the platform-native backend.
Linux requirements#
Published Linux runtimes are built on Ubuntu 22.04 and require glibc 2.35 or newer. The machine must also provide ALSA, OpenSSL 3, fontconfig and the display libraries needed by its active X11 or Wayland session.
Minimal containers and headless Linux systems commonly omit these libraries. Blitsen is a windowed runtime, so a successful install does not imply that such an environment can open an application.
Linux dialogs use the XDG desktop portal and fall back to zenity when no portal is running.
setAlwaysOnTop has no effect on Wayland because that protocol does not expose the operation. Cursor grab modes also vary; the
runtime throws when a requested mode is unavailable. Pointer lock is currently exposed on Windows
and macOS only: pinned winit 0.31.0-beta.3 reports Locked cursor grab as unsupported on X11, and Blitsen
does not claim a Linux API that can fail on a common backend.
On Linux a hidraw node is owned by udev, so a packaged application reaches an intended device only
once a distribution or installer has added a rule granting access; blitsen build writes a
<name>.hid.rules template beside the executable and blitsen doctor reports the requirement.
Blitsen never installs a rule itself and running the application as root is not a supported
substitute.
Application menu#
blitsen/menu is present on macOS and Windows and feature-detectably absent on Linux.
- macOS installs the NSApp main menu. The required application, edit and window roles are always present: Blitsen supplies a standard submenu for each role the application did not claim.
- Windows installs a window menu bar on the application's window. Accelerators work because the runtime translates them inside winit's message pump; a menu bar shrinks the window's client area, as it does for any Win32 application that sets one after creation.
services,showAll,hideOthers,fullscreenandbringAllToFrontare macOS commands and are omitted rather than shown as items that do nothing. - Linux has none. A Linux menu bar is a widget inside the window, and the only backend the menu crate has for one is a
gtk::MenuBarpacked into agtk::Window— Blitsen windows are winit's, the renderer owns the whole client area, and there is no GTK main loop to run it. The desktop-level alternative is the D-Bus global menu, which only some desktops implement and which needs an X11 window id, so it answers nothing on Wayland and would give the same application a menu on KDE and none on GNOME. The tray menu is not this under another name: it belongs to a status item the application may never show.
Notifications#
The standard Web Notification facade is installed on Linux, on Windows, on any macOS process
carrying a bundle identity—an exported application, or a development run inside blitsen
--dev-bundle. It is absent in an unbundled macOS development host.
The native blitsen/notify module is available on every desktop target and exposes
its platform limits directly.
A notification outlives the process that showed it, so activating one belonging to a stopped
application is a launch rather than an event. Blitsen delivers that launch context once, on the
first frame turn, as an activation event on notify.onEvent, and never replays one it has already
delivered—see Native APIs. What each platform does to
produce it differs, and only the parts named here exist:
- Linux — an export with
--bundle-iduses the launch-capable notification portal. The build writes<id>.desktopwithDBusActivatable=trueand<id>.service; once an installer puts those in the standard applications and session-service directories, the runtime owns the same bus name, registers its host connection as that portal application ID (again whenever the portal service restarts) and exportsorg.freedesktop.Application.ActivateAction. Body and named-action targets carry the persisted envelope, and the portal starts a stopped service before invoking it. Calls from any D-Bus peer other than the currentorg.freedesktop.portal.Desktopowner are refused. A development run has no identity and retains the freedesktop live-process backend. The portal has no dismissal/expiry callback or timeout field, and image-file icons require a sealed descriptor this API does not transport, so a packaged app accepts an installed icon-theme name and receives body/action activation and explicitclose, while presentation lifetime and user-dismissal reporting are the desktop's policy. - Windows — an export built with
--bundle-idregisters that AppUserModelID with the notification platform at startup, which is what gives it a notifier of its own and a permission state to read. Packaging also writes a path-independent.notification-register.ps1installer input for the deterministicLocalServer32class, and startup refreshes that path after a portable build is moved. The executable registers anINotificationActivationCallbackclass factory while its event loop is alive. Body and named-action toast arguments contain generation-scoped envelopes; the callback persists one before waking the first eligible frame. - macOS — an exported
.appis relaunched by the notification centre, and the response is delivered to theUNUserNotificationCenterdelegate. Identified exports encode a durable envelope in the native request identifier, and Blitsen's delegate records body, named-action and dismissal responses even when the request was submitted by the previous process. A replacement uses a new generation so a late response cannot consume the replacement's live record.
Where a platform, distribution or installer uses a command-line envelope, the entry point is
--notification-activation <envelope> on the application's own command line; both hosts read it,
and a launch without one is an ordinary launch. Linux portal actions carry the same envelope as the
target of ActivateAction instead.
macOS requirements#
Blitsen publishes Intel and Apple silicon runtimes. The published artifacts are unsigned, and an application you export is unsigned unless your build runs an appropriate signing command.
Distribute a macOS application only after signing its .app bundle and completing notarization on
macOS. Modern macOS notifications also require a signed .app bundle identity, which an export has
and a development run does not: submission and permission from an unbundled executable reject with
a message naming blitsen --dev-bundle, which builds a signed development .app around the
interpreter and runs inside it under com.blitsen.dev.<name>. No installed application's identifier
is ever borrowed for either. Native dialogs are presented as window-modal sheets without blocking
the application frame loop.
blitsen/hid opens devices with shared IOHID access, so an application never seizes a device from
the rest of the system. A sandboxed application must be signed with com.apple.security.device.usb;
blitsen build writes a <name>.app.entitlements file beside the bundle for the signing command to
pass to codesign --entitlements.
Windows requirements#
Published runtimes support Windows 10 or newer, and x64 also supports Server 2016 or newer. The Microsoft C runtime is statically linked, so users do not need a separate Visual C++ Redistributable.
Windows packaging writes the application manifest and optional .ico beside the executable rather
than embedding them in the PE file. Keep those files with the executable. Native dialogs run away
from the window thread and remain modal to it. Single-instance invocation hand-off uses a per-user
named pipe whose name includes the user's SID.
blitsen/hid opens HID top-level collections through the Windows HID class driver and needs no
driver installation. Windows reserves some system collections for itself; an open refused that way
rejects with NotAllowedError, separately from a device that disappeared.
Windows notification permission is what the notifier reports, so it is "granted" or "denied"
and never "default"; requestPermission() reads it without prompting, because Windows gives an
application no prompt to show. Toasts are delivered under an application identity Windows already
knows rather than under appName. An export built with --bundle-id registers that identity at
startup and files its toasts under it; a development run borrows Windows PowerShell's.
Windows keeps that setting per registered AppUserModelID, so a machine that has registered none—an
image stripped of Start Menu entries, such as a CI runner or a Server Core install—has no notifier
to read: permission() and requestPermission() reject there, naming the missing identity, rather
than reporting a state nobody chose.
Mobile#
Android and iOS are not supported. The Android runtime crate, APK tooling and mobile CI have been removed. Mobile can return after supported Bun ports exist and native integration is qualified; Blitsen will not keep a second JavaScript runtime for mobile.
Important runtime limitations#
- WebGL, WebGPU and WebRTC are not implemented.
<canvas>2D is, without shadows orctx.filter. - There is deliberately no platform accessibility tree: semantic elements and ARIA attributes do not expose roles, names, focus state or live regions to screen readers. Keyboard focus and text editing still work through the DOM input path; that does not make the application accessible.
- Editable
<input>and<textarea>controls route winit preedit/commit through composition events into a painted Parley composing range, with candidate-window placement on desktop. Bounded per-control undo/redo includes selection restoration and committed compositions.contenteditable, surrounding-text IME deletion, form reset and advanced selection events remain absent. Native CJK/RTL input has synthetic coverage only and still needs target-specific human verification; static Arabic/RTL and other complex text shaping is a separate tested path. - Font fallback uses installed system fonts plus application-provided
@font-facefiles; no universal fallback is bundled. Ship author fonts for stable coverage and metrics. Platform emoji, colour fonts and ZWJ sequences still need target-specific verification. - Bun provides WebAssembly and its full
Intlimplementation on supported desktop targets. localStoragepersists synchronously under the platform application-data directory;sessionStorageresets with its JavaScript realm.- The runtime is not a browser sandbox and must not run untrusted third-party pages.
This list calls out release-level constraints, not every missing web API. Use blitsen doctor and
Web API support for the complete boundary.
Unsigned artifacts#
The published runtimes are unsigned, and Blitsen does not own or manage your certificates.
Use --sign to connect your build to a signing command, then follow the target platform's normal
distribution and notarization process. A cross-target build can generate packaging files but needs
the target's tools or an external signing service to establish publisher identity.