i99dash docs
Getting started

Quickstart

From zero to a running mini-app in five minutes. Copy-paste the commands; nothing else to configure.

This is the fast path. You'll scaffold a mini-app, run it locally with a simulated host, and publish it to the catalog. ~5 minutes if your machine already has Node 20+.

If anything fails: jump to Troubleshooting. If you want the longer reading first: What is a mini-app?.

Using React?

Skim this page for the CLI flow, then switch to the Next.js guide — it shows the i99dash/react setup (<MiniAppProvider> + hooks) you'll actually ship with. Same init / dev / publish commands.

Prerequisites

ToolVersionCheck
Node≥ 20node --version
pnpm≥ 9pnpm --version
Gitanygit --version

If your machine is fresh, see Installation for a full prereq walkthrough.

1 — Scaffold

pnpm dlx i99dash init my-app
cd my-app
pnpm install

init prompts you to pick a catalog category — it lists the 10 canonical slugs (navigation, media, vehicle, productivity, communication, entertainment, services, lifestyle, developer, other); press 110 or type a slug. Skip the prompt with --yes (defaults to other) or pre-answer with --category media.

You get:

my-app/
├── package.json
├── manifest.json        ← the row the catalog stores
├── sdk.config.json      ← dev-server config
├── src/
│   ├── index.html       ← your app
│   └── assets/
│       └── icon.svg     ← placeholder; swap with your real artwork
└── mocks/
    └── fuel-stations.GET.json

2 — Run locally

pnpm dev

The dev-server boots at http://127.0.0.1:5173. Open it — you'll see a hello-world page. The control panel at http://127.0.0.1:5173/_sdk/ui lets you toggle driving state, device ID, locale, and theme live.

Your first real edit

Open src/main.ts and replace its body with:

import { MiniAppClient } from 'i99dash';

const root = document.querySelector('#root')!;
const ctx = await MiniAppClient.fromWindow().getContext();

root.innerHTML = `
  <h1>Hello from your first mini-app</h1>
  <p>App: <code>${ctx.appId}</code></p>
  <p>Locale: <code>${ctx.locale}</code> · Dark: <code>${ctx.isDark}</code></p>
`;

Save. The dev-server hot-reloads. Open /_sdk/ui and flip the locale — the page re-renders the new value when you reload. That's the bridge working: getContext() reads from the dev-server's shim, the same way it reads from the real host in production.

3 — Validate the manifest

manifest.json is the catalog row for your app. The scaffold creates a minimal one:

{
  "id": "my-app",
  "name": { "en": "My App", "ar": "تطبيقي" },
  "icon": "./assets/icon.svg",
  "url": "https://your-cdn.example.com/my-app/",
  "version": "0.1.0",
  "category": "other"
}

icon is a bundle-relative path (starts with ./) — the file ships in your tarball and the publish flow rewrites the path to a versioned CDN URL automatically. No separate icon upload, no ops ticket. See App icons recipe for the full specs (formats, dimensions, where the file goes per framework).

category must be one of 10 canonical slugs — the head-unit chip rail uses these for navigation. See Categories + tags.

Three rules the backend won't let you bend after publish:

  1. id is forever — it's the deep-link suffix every pinned shortcut carries.
  2. version must increment on every publish.
  3. url must be on the host's allow-list (miniapps.i99dash.app in v1) — coordinate with ops if you need a custom origin.

Full details: MiniAppManifest.

pnpm validate

CI-friendly: exit 0 on valid, exit 3 on schema failure. Catches missing locales, http:// URLs, and other paper cuts before they hit the backend.

4 — Log in

pnpm dlx i99dash login

i99dash login signs the server's one-time challenge with your local SSH ed25519 private key and stores a short-lived access token in your OS keychain. Full flow (incl. CI / headless): Authentication.

5 — Publish

pnpm publish              # validate → build → tarball → upload → submit
# or
pnpm publish --dry-run    # all of the above without uploading

The CLI prints a status URL you can share to track review / rollout. Full reference: Publishing.

That's it

Your app is live in the i99dash catalog. Users who install it from the Store tab get your bundle on next launch.

What just happened?

You connected your code to the host bridge, made a backend-style call through it (well, just getContext() — but every call uses the same mechanism), and shipped a bundle to a CDN catalog. The next page goes deep on the mental model — read it once and the rest of the SDK clicks.

Next

On this page