Getting Started

Quick Start

Get your first Stackable extension running locally in minutes, then deploy it to the marketplace. This guide walks you through scaffolding, previewing, and publishing using the CLI.

Choosing your path

Stackable supports two authoring paths. Both produce the same kind of extension and ship to the same marketplace.

AI Extension StudioCLI (this guide)
Best forPrototyping, learning, quick iterationsProduction extensions, team workflows
Code structureSingle fileMulti-file (surfaces/, components/, lib/)
PreviewBuilt-in live previewLocal dev server + Cloudflare tunnel
AI assistanceSidekick chat + smart insertionSkills, MCP server, and Claude Code plugin (see AI-Accelerated Development)
Version controlAuto-saved to cloudGit-based
DeploymentLink to extension + deployCLI deploy command

Both produce the same output — a Stackable extension that runs inside the embedding application via the same Remote DOM pipeline. This guide covers the CLI path. For Studio, see AI Extension Studio.

Prerequisites

  • Node.js 22 or later
  • pnpm (recommended) or npm

1. Create a New Extension

Scaffold a new extension project:

pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest create my-extension
cd my-extension
pnpm install

This creates a project with:

  • A working extension with header, content, and footer surfaces
  • A local preview host for development
  • TypeScript configuration
  • A manifest with default permissions and targets

2. Preview Your Extension

Run the Stackable CLI dev server from your project directory:

pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest dev

Note: This uses pnpm dlx to run the Stackable CLI without installing it globally. The --config.dlx-cache-max-age=0 flag ensures you always get the latest version.

The dev command:

  1. Starts a local Vite dev server for your extension with hot reload
  2. Creates a public Cloudflare tunnel to your local server
  3. Displays a query parameter you can use to preview your extension

Testing against your extension

The CLI outputs a query param like:

?_stackable_dev=ext-123%3Ahttps%3A%2F%2Fabc.trycloudflare.com

Append this to the host site's URL (the site or product where your extension is installed/authorized) to load your local extension instead of the production bundle. For example:

https://your-host-site.com/dashboard?_stackable_dev=ext-123%3Ahttps%3A%2F%2Fabc.trycloudflare.com

This override is browser-session only — no database changes, no shared state. Each developer gets isolated overrides. Changes made locally appear immediately in your extension via hot reload.

Use --no-tunnel if you only want to run the local Vite dev server without a tunnel.

3. Explore the Project

my-extension/
  packages/
    extension/
      public/
        manifest.json       # Targets, permissions, allowed domains
      src/
        index.tsx           # Entry point — createExtension bootstraps the runtime
        store.ts            # Shared state across surfaces
        surfaces/           # One component per surface slot
          Header.tsx
          Content.tsx
          Footer.tsx
        components/         # Feature components used by surfaces
        lib/                # API wrappers and utilities
    preview/                # Local preview host — DO NOT MODIFY

4. Make Your First Change

Open packages/extension/src/surfaces/Content.tsx and modify the content:

import { Surface, ui } from '@stackable-labs/sdk-extension-react'

export const Content = () => (
  <Surface id="slot.content">
    <ui.Card>
      <ui.CardContent>
        <ui.Heading level={3}>Hello, Stackable!</ui.Heading>
        <ui.Text>My first extension is working.</ui.Text>
      </ui.CardContent>
    </ui.Card>
  </Surface>
)

Save the file — the preview updates automatically.

5. Add a Capability

To read host context data (customer info, etc.):

  1. Add the permission to manifest.json:
{
  "permissions": ["context:read"]
}
  1. Use it in a surface:
import { Surface, useContextData, ui } from '@stackable-labs/sdk-extension-react'

export const Content = () => {
  const { loading, customerId } = useContextData()

  if (loading) {
    return (
      <Surface id="slot.content">
        <ui.Skeleton />
      </Surface>
    )
  }

  return (
    <Surface id="slot.content">
      <ui.Card>
        <ui.CardContent>
          <ui.Text>Customer: {customerId}</ui.Text>
        </ui.CardContent>
      </ui.Card>
    </Surface>
  )
}

6. Submit for review

When your extension is ready, open it in the Stackable admin dashboard, fill in the marketplace listing (icon, screenshots, description, tagline, support links), and submit for review. Most reviews complete within a few business days.

CLI validate and deploy commands are on the roadmap (see CLI Reference). Today, manifests are validated server-side during submission and via the validate_manifest MCP tool.

Next Steps

  • Components — browse the full UI component catalog
  • Capabilities — learn about data.query, data.fetch, and more
  • Surfaces — understand surface types and layout slots
  • Patterns — see common extension code patterns

Auto-generated from Stackable Extension SDK. Questions/Issues? developers@stackablelabs.com

Previous
Overview
Quick Start | Stackable Labs :. Dev Documentation