Open-source React Native framework

Build once.
Publish for people and AI agents.

One codebase. People install it from the stores and get signed over-the-air updates in seconds. AI agents open the very same release in a simulator they can see and operate, so you test the whole app end to end with the assistant you already use. No emulator, no device lab.

$npx -y @shipvo/cli init myshop
Android OTA todayiOS simulator parity 100%Apache-2.0 licensedSelf-host in 10 min
YOU ASK YOUR ASSISTANTBuy a Surface Popper with mobile money. Tell me if anything breaks.
Tide and Tackle home screen Product page for a chrome spoon lure Camera permission dialog Delivery and payment screen
THE AGENT SEES
BACKEND CONFIRMSOrder TT-1001 · 4 200 FCFA
mobile money · receipt SIMULATED-…
Works with the assistants you already use
Claude Desktop · CodeChatGPT connectorCursorPiPilotany MCP client
Live right now
… latest Tide & Tackle release … @shipvo/cli on npm … public apps … api.shipvo.dev … sim.shipvo.dev

Catch the bug before a human, or a phone, does.

The simulator is headless, so every pull request can run your real app flows: permission prompts, payments, notifications, offline. No emulator, no device farm, no phone. A failing test stops the merge, and stops the over-the-air publish too. This repository does it on every push.

tests/checkout.test.ts Typed, in Vitest. Or any runner.
import { test, expect } from "@shipvo/test/vitest";

test("a declined payment places no order", async ({ phone }) => {
  await phone.device.set({
    payment:    { nextResult: "decline", pin: "1234" },
    biometrics: { enrolled: true, nextResult: "success" },
    location:   { latitude: 4.0225, longitude: 9.6967 },
  });
  await phone.tap("Place order");
  await phone.tap("Use fingerprint");
  await phone.type("Mobile money PIN", "1234");
  await phone.tap("Confirm payment");

  await phone.waitFor("Payment declined");
  expect(phone).not.toSee(/Order TT-\d+ placed/);
});
.github/workflows/test.yml Plain ubuntu-latest. Nothing to rent.
on: { pull_request, push: { branches: [main] } }
jobs:
  simulator:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx playwright install --with-deps chromium
      - run: |
          npx shipvo sim --port 4545 &
          # wait for http://localhost:4545/app/
      - run: npx vitest run

# publish.yml: the OTA publish only runs if this passes
publish: { needs: test }
PaymentsApprove, decline, time out, no funds. Assert whether the order was placed.
PermissionsAllowed, denied, never asked. Check the app explains itself.
Location & cameraSet where the phone is, or put a barcode in front of the lens.
Fingerprint & Face IDSuccess, failure, cancel. Every branch, on every commit.
OfflineNetwork off: queued actions, error states, recovery.
Push notificationsDeliver one, open it, assert the right screen.
npm i -D @shipvo/test vitest
Read the testing guide

The simulator renders your app on the web and simulates the device, so it catches logic and flow bugs, not native crashes or slow-phone performance. Where it differs from real Android and iOS, we publish the gaps.

How it works

Four stages, one codebase. Click through; every panel is the real thing, not a mock.

A complete Expo app in one command.

shipvo init writes the OTA runtime, the device API, a simulator build, a publish workflow and your signing key. Your screens use one API for camera, location, biometrics, payments and notifications; it is real on phones and simulated for agents, and never pretends otherwise.

Build your first app →
$ npx -y @shipvo/cli init myshop --name "My Shop"
✓ shipvo.json · app.json · App.tsx · metro.config.js
✓ .github/workflows/publish.yml
✓ .shipvo/seed.txt  (Ed25519 signing key, git-ignored)

// App.tsx
import { device } from "@shipvo/device";
const code = await device.camera.scan();
const here = await device.location.current();
const ok   = await device.auth.confirm("Pay 4 200 FCFA");

One app. Two ways to see it.

The same release, from the same signed bundle. Your customer sees pixels. Your assistant reads the screen like a person would, then taps by reference. This is a real Tide & Tackle screen, not a mock.

Delivery and payment screen of Tide and Tackle
What a customer seesDelivery slots, a mobile money option, one tap to pay.
// what the agent reads, from MCP get_screen
- heading "Delivery and payment" [level=1] [ref=e30]
- heading "Delivery slot" [ref=e31]
- button "Friday 14:00-18:00, 1 500 FCFA" [ref=e33]
- button "Saturday 08:00-12:00, 2 000 FCFA" [ref=e34]
- button "Use my location" [ref=e38]
- textbox "Delivery address" [ref=e39]
- radio "Mobile money" [ref=e41]
- textbox "Mobile money number" [ref=e42]
- button "Place order" [ref=e44]
// then: tap(e44) · the backend receives the order
What an agent readsRoles, names and references. No pixels, no guessing at coordinates.
Publish

One release leaves. Every device gets the same bytes.

You publish once. Phones verify the signature, the hash and the size, apply the update without a restart, and roll back on their own if it fails to boot. Agents open that exact release in the simulator, so what you tested is what shipped.

  • Ed25519signed release pointer, checked on every phone
  • 1 % → 10 % → allstaged by cohort, with one-command rollback
  • tens of KBtypical update, patched from the version a phone already has

a release going out an agent opening it · illustration

Everything an agent-ready app needs.

Each card is a shipped, documented piece. Nothing here is a roadmap item.

PUBLISH

Signed over-the-air updates

Ed25519 pointers, SHA-256 bundles, bsdiff patches, cohort bands, min_shell_version gating and one-command rollback. The shell pins your public key; nothing delivered over the air can change it.

Typical update tens of KB · applied on a 2 GB Redmi 9A without a restart
SIMULATE

A phone agents can operate

Accessibility-tree screens with refs over MCP. Local with npm run sim, hosted with a key from shipvo login.

ChatGPT placed a full order in 18 steps, 76 s
DEVICE

One device API, two truths

Camera, location, biometrics, payments, notifications. Real on phones, simulated for agents, labelled simulated every time.

Receipts say SIMULATED-; logs say simulated: true
VERIFY

Parity, not promises

Nightly runs on an Android emulator and an iPhone simulator; every gap published.

Actionable parity 100 % · text 98.6 % / 96.2 %
MARKETPLACE

Listed for every agent

Flip listing.public and your app appears on shipvo.dev/apps and in every signed-in agent's list_apps.

Review before listing · 3 apps per account in the beta
OWN IT

Self-host in ten minutes, or use ours

The control plane is a Cloudflare Worker with KV and D1. Run it in your account with your keys, or register on the hosted one with shipvo app create; publish tokens are scoped to one app and every pointer is checked against your public key.

api.shipvo.dev hosted · Apache-2.0 everywhere

Numbers, not adjectives.

Taken on a 2 GB Redmi 9A, an Android emulator and an iPhone simulator in CI. Method and gaps in parity results.

100%
Actionable parity, simulator vs device, Android and iOS, 3 flows, 21 screens
parity-results
18 steps
For ChatGPT to scan, locate, pay by mobile money with a fingerprint and reopen the notification. 76 s. Order confirmed by the backend.
agents
<1 s
Cold start of the native shell on a 2 GB Android after an over-the-air update applied without a restart
spike-results
3
Known gaps listed, not hidden: two unlabeled Android dialog buttons and a payment-sheet cancel the Android tree does not expose
parity-results
What the simulator is notIt is not a real device. Payments, biometrics and the camera are simulated and say so. Use it for most of your testing, and a phone for the last mile.
What agents do todayThey test and demonstrate your app. They do not yet buy things for real people through it: that needs OAuth consent, spend limits and a checkout contract, which is on the roadmap, not in the product.

See how it compares, then try it.

Connect the assistant you already use in four steps, read an honest side-by-side with Expo, and check what it costs. We say where Expo is the better choice.

Test with your assistant

The remote MCP path: sign in once, paste one config, and ask Claude, ChatGPT or Cursor to buy something from your app. Prompts that find real bugs included.

Shipvo vs Expo

Simulating and updating, side by side: what each runs, what each catches, and when to use which, or both.

Pricing, with real numbers

Free in the beta, open source always. Worked monthly examples against Expo's plans, and the cost of testing every pull request.

From the blog

Stories and guides, such as the three bugs our first typed test found in our own tooling.

Apps an agent can open right now.

Published with Shipvo and listed by their owners. Sign in once; any MCP client can open_app them. See all →

Private beta

Five developers. One honest hour.

Build and publish an app from the guide alone, then tell us where it broke. Free hosting during the beta and a say in what gets built next.

DM on Xhans@pipilot.dev