NSH (nsh.dev), short for Native Shell, is a Rust engine for cross-platform native UI. You write screens in TSX (with Tailwind classes and signals), in Rust, or both. Each platform draws them with its own UI toolkit instead of a webview. Checked 2026-10-22 against the README, AGENTS.md, docs/dev/ (sandbox, signed packages, compatibility, performance), the installation page, and the GitHub API. I did not install it or run any example.
| Source | GitHub org longbridge, which also publishes gpui-kit (see Web And Desktop Frameworks) |
| License | Apache-2.0 (LICENSE-APACHE, "Copyright 2026 Longbridge"). GitHub's API shows no SPDX id because the file is not named LICENSE |
| Created | 2026-10-14 |
| Latest release | v0.1.1 (2026-10-18); v0.1.0 before it. Cargo.toml on main already says 0.2.0 |
| GitHub | 523 stars, 33 forks, 22 open issues, last push 2026-10-21. Top contributors: huacnlee 116, sunli829 110, madcodelife 37 commits |
| Language | Rust (workspace of ~25 crates under crates/; the website and docs are separate folders) |
What it is
The pitch in AGENTS.md: native UI that is designed to be AI-generated and delivered dynamically. A host app embeds NSH and loads TSX modules at run time as plugins. The modules are signed, sandboxed by the host, and rendered with the platform's own views. Embedding comes first; standalone apps use the same machinery.
Platform backends (from the README table):
| Platform | Drawn with | Embed with | Needs |
|---|---|---|---|
| iOS | UIKit, CoreText | NshAppView (Swift, NativeShell.xcframework) |
iOS 15+ |
| Android | Android views | NshView (Java/Kotlin, nsh.aar) |
Android 9 (API 28)+ |
| macOS | AppKit, Core Animation | AppView (Rust crate) |
macOS 14+ |
| Windows | Win32, Direct2D, DirectWrite | AppView (Rust crate) |
Windows 10 1809+ |
| Linux | GTK 4, Pango | AppView (Rust crate) |
GTK 4.14+ |
| GPUI (desktop) | GPUI | a GPUI view | macOS, Windows, or Linux with Vulkan |
| Web | HTML, CSS | createPlayer (JS) or an iframe |
modern browsers |
How it is built
- JS runs in QuickJS inside a native runtime. The reactive graph (Solid's algorithm), the renderer, and every module an app imports are Rust. Layout uses Taffy (flexbox and grid).
- Layering copies GPUI Kit:
nsh-coreplays the role ofgpui(primitives, layout, rendering) andnsh-baseplaysgpui-base(unstyled behavior, focus, accessibility). A styled component library is deliberately not part of NSH; apps build their own onnsh-base. - The toolchain is pure Rust and needs no Node.js. App developers get a prebuilt
nshbinary and, for TSX apps, need no Rust either. AGENTS.mdand the docs say the main thread never waits for JS, and performance is the project's "first priority".
Sandbox and signed packages
From docs/dev/sandbox.md and signed-packages.md:
- Apps embedded in another app get limits that the host sets (defaults in the doc: 256 MB heap, 4 MB stack, 10 s to load, 2 s per call, 200,000 nodes). Standalone apps run with no heap or time limit.
- Hardening is on unless the bundle came from a dev server:
evalis deleted,Functionconstructors throw, shared prototypes are frozen. - Capabilities are declared in
nsh.json(network hosts and methods, web view hosts, process execution, file-system roots, clipboard) and enforced in Rust. - Packages (
.nshpkg) are signed by a release key, which a root key certifies. Keys rotate without app updates. The doc notes that QuickJS does not validate bytecode, so loading untrusted bytecode isunsafeand downloaded code is either JS source or a signed package.
Compatibility promise
docs/dev/compatibility.md says every release must run every app built for an earlier one, and an app that breaks after an update is "a bug in NSH, never in the app". That promise holds "from the first release recorded in nsh-compat on", and it is enforced with tests/compat/. With the version at 0.1.x this is a stated intention, not a track record.
Quick start
curl -fsSL https://nsh.dev/install.sh | sh # or: brew install longbridge/tap/nsh
nsh init my-app --template ts # or rust, or mixed
nsh run my-app --target macos # ios, android, windows, linux, gpui, web
Other commands in the README: nsh package --target web publishes a static site, nsh publish signs a package, nsh test runs a headless trace (--trace), and cargo run in the repo runs the gallery. Examples live in examples/ (gallery, counter, hopper dashboard, desktop, embed-ios, embed-android, embed-gpui, bench).
Where it fits
NSH is closest to React Native in aim (JS-authored UI rendered by native views), with a Rust core instead of a JS-bridge runtime. Unlike MyGo, Tauri, or Electron, it does not put a webview at the centre; the web is just one more target. What sets it apart in its own docs is the plugin story: signed, capability-limited TSX delivered to a native host, plus model-readable docs at nsh.dev/llms.txt for generating screens. It also builds on GPUI ideas (typed units, SharedString, API vocabulary), shadcn/ui tokens for the default theme, and Solid for reactivity (README acknowledgements). These comparisons are my reading of the docs, not tested head to head.
Caveats
- Weeks old and pre-1.0 (v0.1.1; main is already 0.2.0). Expect API churn despite the compatibility pledge.
- Performance numbers in
docs/dev/performance.mdare the authors' own, mostly headless debug builds on Apple Silicon (for example a counter's first frame of about 0.5 to 0.65 ms). I did not reproduce them, and the doc itself warns that single-frame timings depend on CPU clock state. - Each platform backend is separate code, so behavior can differ by OS. The docs have per-backend "what differs" sections that I did not read in full.
- The GitHub license badge reads NOASSERTION. The text is Apache-2.0, so it only looks unlicensed to the API.
- Not checked: the
nsh.devlive demos, the Chinese docs, the Android and iOS embedding paths, and whether the AI-generation workflow produces good screens in practice.
See also Ely GPUI and Web And Desktop Frameworks.