Deploy like a website
Push your SPA to your normal CDN or static host. The native shell loads it at runtime, so most content and feature updates ship without an app-store review or a new binary.
Hull wraps your web SPA in a thin, auditable iOS and Android shell, with the same build also running in the browser. Most changes deploy through your normal web pipeline — no app-store review, no binary rebuild. One codebase, one deploy flow, three platforms.
import { hull } from "@hull/web-sdk";
const env = await hull.initialize();
await hull.app.webContentReady();
const photo = await hull.camera.takePhoto({ quality: 0.9 });
await hull.secureStorage.set("lastScan", photo.uri);
Push your SPA to your normal CDN or static host. The native shell loads it at runtime, so most content and feature updates ship without an app-store review or a new binary.
Every native call is a named, versioned JSON envelope. The web app gets typed promises, not raw native objects.
If the hosted SPA fails to load, the shell instantly falls back to a known-good build shipped inside the app binary.
React, Vue, Svelte, Angular, or plain TypeScript. Hull only cares about the bridge contract, not your UI library.
The manifest + typed bridge give agents a discoverable, capability-aware API. Automate tests, fleet tasks, or workflows without driving UI.
No third-party SDK taxing your installs or hiding the platform. The shell is open source, auditable, and yours.
Use the frameworks and deployment pipeline you already know. Vite, Next.js, or plain HTML — it all works.
One JSON file tells the native shell the remote URL, allowed origins, theme, auth provider, and exposed capabilities.
Call `hull.initialize()` in your SPA, then `hull.app.webContentReady()`. Device features become typed promises.
The generic native shell bundles your SPA as a fallback and loads the remote version whenever the device is online.
Clone the repo, run the proof-of-concept, and see a web SPA talk to a native shell in minutes.