Reeve
Developers

Getting Started

Scaffold your first Reeve app with create-reeve-app and see it running inside the Cockpit in under 5 minutes.

Getting Started

Build your first Reeve app in 5 minutes. You'll scaffold a project, run it locally, and install it into the Cockpit — all before your coffee gets cold.

Prerequisites

  • Node.js 18 or later
  • A Reeve account with Cockpit access (sign up free)
  • Developer preview access (apply here)

Create Your App

Run the scaffolding CLI:

npx create-reeve-app my-app

You'll be prompted to choose a template:

? Select a template:
❯  react-app       — React + Vite (recommended)
   agent-app       — Custom AI agent
   embed-app       — Lightweight widget
   vanilla-app     — No framework

Choose react-app for your first app. The CLI creates a new directory with everything pre-configured.

Install Dependencies and Start Dev Server

cd my-app
npm install
npm run dev

Your app runs at http://localhost:5173. You'll see a blank page — that's correct. Reeve apps are designed to run inside the Cockpit iframe, not standalone.

Install Your App into the Cockpit

  1. Open app.meetreeve.com and log in
  2. Navigate to Settings → Apps
  3. Click Install from URL
  4. Enter http://localhost:5173
  5. Click Install

Your app appears in the App sidebar. Click it — you should see the default starter UI.

The Cockpit loads your app in a sandboxed iframe. Your local dev server must be running, and the URL must be accessible from your browser (not inside a Docker container or remote server without port forwarding).

Make a Change

Open src/App.tsx in your editor. You'll see the starter component:

import { useEffect, useState } from 'react';
import { reeve } from '@reeve/app-sdk';

export default function App() {
  const [config, setConfig] = useState(null);

  useEffect(() => {
    reeve.init().then(setConfig);
  }, []);

  if (!config) return <div className="loading">Connecting to Reeve...</div>;

  return (
    <div className="app">
      <h1>Hello from Reeve!</h1>
      <p>Org: {config.orgId}</p>
      <p>Theme: {config.theme}</p>
    </div>
  );
}

Change the heading to something else. Save the file. Switch back to the Cockpit — the iframe reloads automatically via Vite HMR.

Make Your First API Call

Let's fetch some Shopify orders. Update src/App.tsx:

import { useEffect, useState } from 'react';
import { reeve } from '@reeve/app-sdk';

export default function App() {
  const [orders, setOrders] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function load() {
      await reeve.init();

      const result = await reeve.data.query({
        source: 'shopify',
        type: 'orders',
        filters: { status: 'fulfilled' },
        limit: 5,
      });

      setOrders(result.data);
      setLoading(false);
    }

    load();
  }, []);

  if (loading) return <p>Loading orders...</p>;

  return (
    <ul>
      {orders.map((order) => (
        <li key={order.id}>
          Order #{order.name} — ${order.total_price}
        </li>
      ))}
    </ul>
  );
}

Update your manifest to add the data.shopify permission (see below), then save. The Cockpit reloads and you'll see real order data.


Project Structure

After scaffolding, your project looks like this:

my-app/
├── reeve-manifest.json   ← App metadata and permissions
├── src/
│   ├── App.tsx           ← Main component
│   ├── main.tsx          ← Entry point
│   └── index.css         ← Global styles
├── public/
│   └── icon.png          ← App icon (required for Marketplace)
├── index.html
├── package.json
└── vite.config.ts

The Manifest

reeve-manifest.json declares your app's identity and permissions. The Cockpit reads this file when your app is installed:

{
  "id": "com.yourcompany.my-app",
  "name": "My App",
  "version": "1.0.0",
  "description": "A short description shown in the App Store.",
  "author": {
    "name": "Your Name",
    "email": "you@yourcompany.com",
    "url": "https://yourcompany.com"
  },
  "category": "analytics",
  "permissions": [
    "data.shopify",
    "ai.complete",
    "storage.read",
    "storage.write"
  ],
  "entrypoint": "index.html",
  "icon": "public/icon.png"
}

Full manifest reference → Manifest Reference

SDK Initialization

Every app starts with reeve.init(). This handshakes with the Cockpit, validates permissions, and returns the current context:

import { reeve } from '@reeve/app-sdk';

const config = await reeve.init();
// config = {
//   orgId: 'org_abc123',
//   userId: 'usr_xyz789',
//   theme: 'dark',
//   locale: 'en-US',
//   appId: 'com.yourcompany.my-app',
//   permissions: ['data.shopify', 'ai.complete', ...]
// }

Call reeve.init() once, as early as possible. All other SDK methods require initialization to complete first.

Theming

Your app should match the Cockpit's active theme. The SDK exposes CSS variables you can use directly:

/* These are automatically injected into your iframe */
:root {
  --reeve-bg: #0f0f0f;
  --reeve-surface: #1a1a1a;
  --reeve-border: #2a2a2a;
  --reeve-text: #f0f0f0;
  --reeve-text-muted: #888888;
  --reeve-accent: #6366f1;
  --reeve-accent-hover: #4f46e5;
  --reeve-radius: 8px;
  --reeve-font: 'Inter', system-ui, sans-serif;
}

Listen for theme changes at runtime:

reeve.onThemeChange((theme) => {
  document.documentElement.setAttribute('data-theme', theme);
});

Next Steps

On this page