Skip to main content
This guide walks you through creating a Stratos plugin from scratch — a React component that appears in the Stratos sidebar with live reload during development.

Prerequisites

  • Node.js 20+
  • pnpm (recommended)
  • The Stratos app installed with --dev flag access

1. Scaffold your plugin

The fastest way to get started:
pnpx create-stratos-plugin
This prompts you for a plugin name, author, and type, then generates a ready-to-develop project with Tailwind CSS, TypeScript, and Vite preconfigured. Your project structure:
my-plugin/
├── .gitignore
├── plugin.json           # Plugin manifest
├── package.json
├── vite.config.ts        # Build config (uses SDK)
├── tsconfig.json
├── src/
│   └── ui/
│       ├── index.tsx     # UI entry point
│       └── global.css    # Tailwind CSS
└── assets/
    ├── icon-light.svg    # Sidebar icon (dark theme)
    └── icon-dark.svg     # Sidebar icon (light theme)
Install dependencies:
cd my-plugin
pnpm install

2. Understand the key files

plugin.json

Every plugin needs a manifest. The scaffolder generates this for you:
{
  "$schema": "https://cdn.skyvexsoftware.com/schemas/stratos-plugin.json",
  "id": "my-plugin",
  "type": "airline",
  "name": "My Plugin",
  "version": "0.1.0",
  "description": "A custom plugin for our VA",
  "author": {
    "id": "my-va",
    "name": "My Virtual Airline"
  },
  "icon_light": "icon-light.svg",
  "icon_dark": "icon-dark.svg"
}
The id must be unique — lowercase alphanumeric and hyphens only. The type controls distribution: "airline" plugins are synced to all pilots by the VA; "user" plugins are installed individually.

vite.config.ts

import { createPluginConfig } from "@skyvexsoftware/stratos-sdk/vite";
import tailwindcss from "@tailwindcss/vite";

export default createPluginConfig({
  ui: { entry: "src/ui/index.tsx" },
  vite: {
    plugins: [tailwindcss()],
  },
});
createPluginConfig handles everything: externalising shared dependencies (React, TanStack Query, the SDK), ESM output format, asset copying, and dev server auto-connect. The vite option lets you add extra Vite config like Tailwind.

src/ui/index.tsx

Your plugin’s root component. Must be the default export:
import { usePluginContext } from "@skyvexsoftware/stratos-sdk";
import "./global.css";

export default function MyPlugin() {
  const { pluginId, airline } = usePluginContext();

  return (
    <div className="p-6">
      <h1 className="text-2xl font-bold">
        Welcome to {airline?.name ?? pluginId}
      </h1>
      <p className="text-muted-foreground mt-2">
        Your plugin is running!
      </p>
    </div>
  );
}
The shell mounts this component at /plugins/my-plugin and wraps it with providers that supply plugin context, error boundaries, and theme.

3. Develop with live reload

Start the Stratos app with the --dev flag, log in, and select your airline. Then in your plugin directory:
pnpm dev
You’ll see:
✓ Vite dev server running at http://localhost:5174
✓ Connected to Stratos (localhost:2066)
✓ Plugin "my-plugin" mounted
Your plugin appears in the Stratos sidebar immediately. Edit your code — changes auto-reload in about a second.

4. Build for distribution

When you’re ready to ship:
pnpm build
This produces a dist/ directory:
dist/
├── plugin.json
├── assets/
│   ├── icon-light.svg
│   └── icon-dark.svg
└── ui/
    └── index.js
Zip the dist/ directory and upload it to the Skyvex website.

Adding a background module

If your plugin needs server-side functionality (Express routes, IPC handlers, database access), add a background module:
  1. Create src/background/index.ts:
import type { PluginContext } from "@skyvexsoftware/stratos-sdk";

export async function onStart(ctx: PluginContext) {
  ctx.logger.info("MyPlugin", "Background started");
}

export async function onStop() {
  // cleanup
}
  1. Update vite.config.ts:
export default createPluginConfig({
  ui: { entry: "src/ui/index.tsx" },
  background: { entry: "src/background/index.ts" },
  vite: {
    plugins: [tailwindcss()],
  },
});
  1. Add cross-env and update build scripts in package.json:
{
  "scripts": {
    "dev": "vite",
    "build": "vite build && cross-env BUILD_TARGET=background vite build",
    "build:ui": "vite build",
    "build:bg": "cross-env BUILD_TARGET=background vite build"
  }
}
See Background Module for the full API reference.

Next steps