Skip to content

Differences from browsers

Checked against 2994ef5 on 2026-11-10 by Capy (review pass: Subagent 124 and fable). The files it covers are unchanged since.

Most of what differs between niso and a browser is a missing feature, which Web platform support and each Web API page show. This page lists the differences that are by design, or that follow from niso being an app rather than a browser.

  • One document per app. There is no navigation between documents; apps are single-page apps. History works within the document. The system’s back gesture or button isn’t routed to the page yet; DECISIONS.md plans for it to call history.back() (Navigation).
  • The app’s origin. A native app’s document is at about:blank with the app’s origin for storage, https://<app>.app.niso or what the host sets (iOS and Android use the bundle id or package name), so location and relative URLs behave as for about:blank (Storage).
  • Trust. A page has its host’s trust: there is no sandbox between the page and the app, and every origin’s scripts share one process. niso applies CORS to cross-origin reads, but has no cookies, HTTP authentication or HTTP cache, and no Content Security Policy, CORP, COEP or COOP (Security).
  • Native controls. <button>, <input type="checkbox" switch>, range inputs, <progress>, text fields and radio groups are the platform’s controls when their appearance isn’t none. Each accepts a fixed set of CSS properties; others are ignored. A radio group can become a segmented control. In a browser the same page shows the browser’s controls (Native controls).
  • Text is drawn by the platform. niso lays text out with Parley and the platform draws the glyphs, so glyph rendering, hinting and font fallback look like the platform’s, not Chrome’s. Layout is compared with Chrome’s; text’s look is not (Text).
  • Scrolling is native, with the platform’s physics and indicators.
  • Defaults follow the platform where a page asks for it with the niso-platform-style meta; without it, a page renders as in a browser (Platform style).
  • Safe areas. stylo’s env(safe-area-inset-*) is always 0, so hosts publish the insets as --niso-safe-area-inset-* for a page with viewport-fit=cover. The small, large and dynamic viewport units all equal the viewport until stylo resolves them.
  • CSS built only for Firefox. niso uses Servo’s build of stylo, which leaves out what stylo builds only for Firefox. accent-color is dropped when it’s parsed (repros/stylo-accent-color-gecko-only), so a page’s accent-color reaches no control. prefers-reduced-motion, prefers-reduced-transparency and prefers-contrast never match, and the AccentColor system color is stylo’s fixed blue rather than the user’s (repros/stylo-servo-user-preference-media-features). A page with the niso-platform-style meta gets the user’s accent as --niso-color-accent instead (Platform style). prefers-color-scheme, color-scheme and light-dark() work.
  • Effects. box-shadow, filter and backdrop-filter are drawn with the platform’s own effects. A blurring backdrop-filter is Liquid Glass on iOS 26 and later, a blur material before; Android draws the translucent background without the blur.
  • Engines. On QuickJS and Porffor, Intl comes from niso’s own implementation on ICU4X (Intl notes), and WebAssembly runs on wasmi, an interpreter, since iOS forbids JIT (WebAssembly notes). Under Node, Deno and Bun the engine’s own Intl and WebAssembly are used.
  • Workers. Dedicated workers only: there are no shared workers, service workers or shadow realms. A worker’s IndexedDB is in memory and its own (Workers).
  • The mouse is pointer 1 and always active, as in Chrome, so setPointerCapture(1) never throws.

Features about a browser’s own UI, such as alert, downloads, printing, window.open, notifications and the clipboard, have a native meaning in niso (the platform’s dialog, share sheet, print APIs, a new window or scene). The mapping is in the WPT notes; which of them are implemented is in Web platform support.