Repository navigation
RFC: NativeScript Edge — previews on NativeScript's own infrastructure, for phones and, for the first time, desktops #63
Replies: 1 comment 1 reply
|
My little analysis of this with the help of AI: The problem is already solved. We lost two examples, and website#100 fixes that by backing the StackBlitz links with GitHub. Edge solves a much bigger problem than the one we actually had. What StackBlitz gives us that Edge doesn't: Someone else runs it. Uptime, security, abuse, scaling and cost are StackBlitz's problem. With Edge, every one of those becomes NativeScript's problem, and the RFC doesn't say who owns them. It works like a real project. It uses real npm packages, a real build, and the same toolchain people use locally. Edge runs remote ES modules with no bundler and no npm, so it teaches a workflow that new users won't use when they build an actual app. It's low-risk for us. It doesn't execute remote native code on users' phones or desktops under our name. What Edge adds in exchange: A permanent service for a small team to operate. That means deploys, quotas, abuse handling, model spend, incident response and support, with an unclear owner and a single point of failure in whoever maintains it. A large security and liability surface. Remote code execution on devices, an AI agent with native access, desktop hosts with full user privileges, and anonymous hosting under nativescript.org. Fragmentation. Two preview paths, two development models, and a second CLI entry point. Bug reports and docs both get harder. Store risk to Preview. Remote agent control and paid tiers make the App Store education exception harder to defend. My view: the GitHub-backed StackBlitz links fix the actual problem at almost no ongoing cost. Edge may have value as an experiment or as a separate nstudio product, but adopting it as NativeScript's official front door commits the project to running a service with real security and maintenance costs. The RFC doesn't show that we can sustain that, or that we need to. |
Uh oh!
There was an error while loading. Please reload this page.
RFC: NativeScript Edge — previews on NativeScript's own infrastructure, for phones and, for the first time, desktops
@nativescript/edge-*npx @nativescript/edge-cli live(phone),live --desktop(Mac or Windows),live --electron,live --exponstudio/ns-cloudflare(to move to the NativeScript org, see Unresolved questions) · Preview 3.0: preview#38 ·ns live: nativescript-cli#6184@nativescript/react-nativeon react-native-macos), #112 (on react-native-windows), windows#46 (merged)Summary
Today, trying NativeScript without installing anything means a StackBlitz project that runs
@nativescript/preview-cliin a WebContainer, builds a webpack bundle in the browser, and relays it to the NativeScript Preview app through a session worker. Every link on nativescript.org, every "Try it" button and every docs snack depends on that chain, and on StackBlitz keeping each saved project intact.This RFC proposes that NativeScript own the preview loop end to end:
preview.nativescript.org/p/<id>. Phones and desktop hosts load its ES modules over HTTP and hot-reload as people, or an AI agent, edit.@nativescript/. The server is one package; everything else speaks a small open protocol to whatever server it's pointed at.Motivation
We lost two examples we didn't own
The Angular and Svelte "Try it on StackBlitz" links on nativescript.org opened saved projects (
nativescript-battery-example-angularand-svelte) that had been there for years. StackBlitz moved both to new storage, and the files didn't survive the migration. The owner couldn't restore them: saving returned409 Conflictand the editor crashed. nativescript-website#100 points the links at GitHub-backed branches instead (stackblitz-examples#3), which fixes the symptom.The cause is structural. Our front door depends on:
@nativescript/stackblitzinstalls@nativescript/preview-cli@lateston every boot, and the templates resolve their dependencies fresh, so they drift. Today the Vue template fails to build against current webpack, the Angular template resolves an@nativescript/angularthat needs core 9 while pinning core 8.9, and XML apps on core ≤ 8.7 render blank on Android under webpack 5.112. None of these are bugs in NativeScript, and none can be fixed from the Preview app;When any piece breaks, the first thing a new developer sees is a blank editor or a blank phone.
What changed
NativeScript 9.1 made the runtime a standards-based ES module host. The loader fetches
https://modules, keys its registry on canonical URLs, takes import maps, evicts entries withns:module'sinvalidateModules(), and release builds can allow remote modules from an allowlist. A prebuilt NativeScript app can now run code it has never seen, served as plain ES modules by any HTTP server, with full synchronous access to every native API.Cloudflare made compute addressable per entity. A Durable Object gives one project a single-threaded home with SQLite and hibernating WebSockets, so an idle project costs nothing and a saved one stays saved. Dynamic Workers start isolates from code strings, so a project can carry its own backend.
Together, a NativeScript app's code doesn't have to live on a laptop or in a browser tab. It can live at an address, and phones, desktops, editors and agents are all peers of that address.
Why it matters beyond fixing examples
@nativescript/macos-node-api) and a Windows runtime (@nativescript/windows-napi, rfcs#61). Until now there was no way to show someone a NativeScript desktop app without them cloning, installing and building it. With this, a link opens it, in the browser, streamed from a real Mac or PC, andlive --desktopruns it locally with hot reload.@nativescript/react-native. Each is one command, without adopting the NativeScript CLI first.screenshot,viewTree,runOnDevice(JavaScript with full native API access on the device),readDeviceLogs. Claude Code, Cursor or the IDE's own agent can write NativeScript and check it on a real screen. The agent is required to confirm each change in a screenshot, so it can't claim success it didn't see.live --from expo-settings, gallery at /p/samples) never expire once approved, and their source is also kept in git.Guide-level explanation
Phones
From an empty folder: creates a project, opens the browser IDE, and prints a QR code. Scanning it opens the project in NativeScript Preview 3.0 (iOS TestFlight build 13; Android on the Play testing track), which shows the app with no chrome over it. Every save hot-reloads it.
ns livein the NativeScript CLI forwards to the same command (nativescript-cli#6184).Frameworks: TypeScript/XML by default,
--ng,--react,--vue,--svelte,--solid. Preview loads each framework on demand.Desktops
npx @nativescript/edge-cli live --desktop # --mac and --windows are aliasesOn an Apple Silicon Mac (macOS 14.4+) or a Windows 10 1903+ / Windows 11 PC, with Node 22.15+. The template is one settings window built twice from shared logic:
app/macos.tswith AppKit,app/windows.tswith Windows.UI.Xaml, chosen at run time. The window opens on your machine and streams into the IDE's Device pane, where anyone with the IDE open can click and type into it.The IDE and the agent
The IDE at
/p/<id>/is a VS Code-style workbench: Monaco with per-project types (core, every iOS, Android or macOS framework, Node, Electron, the project's framework), Problems, device output, a live device mirror with its view tree, and the agent docked on the right. The agent has a few free turns a day on the hosted model; people can add their own Anthropic or OpenAI key (kept in their browser and never stored), or connect any MCP client.Your own editor
Or mirror from a Vite dev server with the CLI's Vite plugin. The project's keys live in
.ns-edge.jsonin the folder.Sharing
/p/<id>/#key=<writeKey>): edit./p/<id>#<deviceKey>): run. Opened in a browser, it shows the project read-only with its run command and Fork to Edit.edge-cli submit <name>, or Submit as a Sample… in the IDE). Once reviewed,live --from <name>and/p/<name>reach it for good.Reference-level details
Architecture
Design decisions
hello→boot/update/rpc. Devices pull modules over HTTP; the socket never carries source. Any server or host that speaks it interoperates.?v=hashes its source and its imports' versions (cycles hash as one unit). An edit re-versions only that module and its importers, so hot reload is justimport(newEntryUrl): the runtime's own registry skips everything unchanged, and untouched modules keep their state. Versioned responses are immutable and cached at each Cloudflare location, so fifty phones on one project cost one transform per change.@nativescript/core, and an import the binary can't satisfy fails at the edge with a readable error instead of a native crash.web/pages are CSP-sandboxed and aren't served for free projects at all; raw files aretext/plainwithnosniff.Measured
live --macfrom an empty folder, productionlive --electron, productionlive --expo, productionStore policy
Preview runs downloaded code, which App Review allows for educational apps (guideline 2.5.2), and its store listing shows only its own UI with learning-focused copy. Its release build allows remote modules only from
https://preview.nativescript.org/p/. The development shell in the repo refuses remote modules in release builds and is never submitted to a store. Nothing here is a way to update a store app's features over the air.Free tier
Projects created without a token are free: up to 30 per network a day, 20 hosted agent turns per project a day (a global daily cap bounds total model spend), no
server/backend orweb/pages, and deletion after 30 days unused. Turns made with a person's own model key don't count. Accounts (GitHub sign-in, a per-account allowance, then an optional paid plan for backends and non-expiring projects) are designed but not built.The packages
Every package is Apache-2.0 under
@nativescript/edge-*. Onlyedge-cloudflaredepends on where it's hosted.@nativescript/edge-protocol@nativescript/edge-cloudflare@nativescript/edge-shellEdgeClient, pairing links with consent)@nativescript/edge-clilive,create,pull,watch,push,qr,samples,submit,--from, and a Vite pluginns liveforwards to it@nativescript/edge-desktopmacos-template projects with AppKit on a Mac or Windows.UI.Xaml on Windows, captures the project's window (ScreenCaptureKit /RenderTargetBitmap) and takes input from the IDE@nativescript/edge-electron@nativescript/edge-expo-desktop(+-win32-x64)@nativescript/react-nativelinkedIt also depends on, and has driven fixes into, NativeScript's runtimes:
https://imports, import maps,invalidateModules, remote-module allowlists@nativescript/macos-node-apiinterop.releaseNativeObject), #104 (metadata targets the SDK, not macOS 11, soSCStreamandNSGlassEffectViewexist)@nativescript/windows-napi@nativescript/react-nativeLinux
Linux isn't built yet, and the design is ready for it. A Linux host needs:
HostPlatformimplementation inedge-desktop(device info, window bookkeeping, capture, input). The Mac and Windows ones show its shape.Nothing else changes: the protocol, the server, the stream relay, the IDE and the agent are platform-neutral. A Linux runtime would get a preview loop, a browser IDE and an agent on its first day.
Drawbacks
pull; samples live in git; the server is one package behind an open protocol, so another host is a sibling package rather than a rewrite. StackBlitz's case was the opposite on every count.@nativescript/mlkit-*3.0.4 crashing iOS at launch blocks the in-app QR scanner and the rest of the catalog. Custom development clients throughedge-shellare the long-term answer..ios.ts/.android.tsqualifiers aren't resolved yet; desktop streams are JPEG (H.264 is blocked on a VideoToolbox callback deadlock); press-and-hold input isn't possible yet.Alternatives considered
Adoption plan
@nativescript/mlkit-*iOS launch crash is fixed and the QR scanner is back.ns live(nativescript-cli#6184), deciding between following@latestand pinning a version.live --ios,--android), and Linux once a runtime exists.Unresolved questions
NativeScript/edge?) for the server, CLI and hosts, or split the shell and protocol into their own?edge-shell?All reactions