Developer docs/Get started

Connect an existing web app

Bring your React, Vue, or static frontend into Trove with a manifest and the Web SDK.

Verified September 11, 2026

On this page

Check the integration boundary#

This guide assumes you have a frontend that can build to static HTML, JavaScript, and CSS. Trove loads those assets in its WebView. React and Vue can use the same SDK; no Trove-specific rendering framework is required.

An SSR server is not automatically bundled or hosted by Trove. Export a static client or move the necessary native/server logic into a Backend. Keep credentials and native-only modules out of your browser bundle.

Obtain the matching SDK#

Run the adoption wizard in the existing project root:

sh
cd my-web-app
trove adopt
npm install

Choose the name, ID, production HTML entry, package manager, existing dev/build scripts and dev URL. This example uses npm; use the corresponding install command for your manager. Adoption adds curio.json, the matching local SDK and its dependency entry, preserving application source, other dependencies and scripts. Cancelling the wizard writes nothing.

If a manifest already exists, run trove kit and reinstall dependencies. Commit vendor and lockfiles. No temporary starter is needed to obtain the SDK.

Review the manifest#

Review the curio.json created by the wizard. This complete UI-only example assumes npm scripts named dev and build, with production output in dist/:

json
{
  "schemaVersion": 1,
  "id": "dev.example.my-web-app",
  "name": "My Web App",
  "version": "0.1.0",
  "engine": { "trove": ">=0.0.1-alpha.1 <0.0.2" },
  "ui": { "entry": "dist/index.html" },
  "development": {
    "ui": {
      "url": "http://127.0.0.1:5173",
      "command": ["npm", "run", "dev"]
    }
  },
  "build": { "command": ["npm", "run", "build"] },
  "package": { "files": ["dist"] }
}

Change the ID, display name, output path, and commands to match your project. ui.entry is a local production HTML file; development.ui.url is the development address. Do not put a remote website URL into ui.entry.

Align the development and asset paths#

For Vite, merge these settings into your existing config and keep its framework plugins:

ts
import { defineConfig } from "vite";

export default defineConfig({
  base: "./",
  server: { host: "127.0.0.1", port: 5173, strictPort: true },
  build: { outDir: "dist" },
});

Relative asset URLs keep JavaScript and CSS resolvable from the packaged entry. Check images, fonts, lazy imports, and navigation after packaging. For a single HTML entry, hash-based client routing avoids requiring an HTTP history fallback.

If your server is already running, connect to it without starting a second process:

sh
trove dev --no-start-ui --ui-url http://127.0.0.1:5173

For simultaneous projects, use distinct fixed ports or adopt the template’s dynamic port setup described in local development.

Connect from your UI#

Call from an event handler or client lifecycle and show loading, success and failure states:

ts
import { host, TroveError } from "@trove/plugin-sdk";

export async function inspectHost() {
  try {
    return await host.runtime.getHostInfo();
  } catch (error) {
    if (error instanceof TroveError) {
      console.error(error.code, error.message, error.traceId);
    }
    throw error;
  }
}

Calls wait for connection readiness; you can also use await host.ready() explicitly. Importing the SDK is lazy. Use a separate mock in a regular browser and surface native failures honestly.

Verify both modes#

  1. Run trove check from your project. Resolve manifest and dependency errors.
  2. Run trove dev; confirm the UI and a real Host response.
  3. Stop that session, run trove pack, and install the archive with trove install.
  4. Open the installed Curio with the UI server stopped. Exercise navigation and asset loading, then repeat the native call.

A working development URL alone does not verify the packaged application. See distribution for file selection and native runtime requirements.