> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Building a NaaP plugin

> Create, develop, and publish NaaP plugins using the @naap/plugin-sdk CLI. Scaffold, hot-reload, access shell services, and publish to the registry.

export const CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

<CenteredContainer preset="readable90">
  <Tip>The @naap/plugin-sdk CLI scaffolds a plugin, starts a hot-reload dev server inside the NaaP shell, and packages the plugin for publishing. Three commands from zero to running plugin.</Tip>
</CenteredContainer>

<CustomDivider />

## Building a plugin

NaaP has full tooling for plugin development and publishing. If you are building a network tool - a monitoring dashboard, a governance interface, an AI pipeline manager - shipping it as a NaaP plugin gives you shared auth, navigation, and database infrastructure with zero setup.

**Install the CLI and scaffold a plugin:**

```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
npm install -g @naap/plugin-sdk
naap-plugin create my-plugin
naap-plugin dev
```

The dev server hot-reloads your plugin inside the shell at `http://localhost:3000`. The `start.sh` script manages the full platform locally:

```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
git clone https://github.com/livepeer/naap.git && cd naap && ./bin/start.sh
```

First run handles everything: dependency installation, PostgreSQL via Docker, schema creation, `.env` generation, plugin bundle builds, and platform start. Subsequent starts take 6-8 seconds.

**Every plugin declares a `plugin.json` manifest:**

```json icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "id": "my-plugin",
  "name": "My Plugin",
  "version": "0.1.0",
  "category": "developer",
  "permissions": ["network:read"]
}
```

Plugins access shell services through the SDK hooks:

```typescript icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import { useShell, useAuth, useEventBus } from '@naap/plugin-sdk';

export function MyPlugin() {
  const { navigate, notifications } = useShell();
  const { user } = useAuth();
  const eventBus = useEventBus();
  // ...
}
```

All plugin API calls go through `/api/v1/my-plugin/*` using the standard response envelope:

```typescript icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
// Success: { success: true, data: T, meta?: { page, limit, total } }
// Error:   { success: false, error: { code, message } }
```

NaaP also ships AI prompt templates for building plugins without writing boilerplate. The [Prompts section](https://operator.livepeer.org/docs/prompts/how-to-use) in the NaaP docs covers 8 templates covering frontend plugins, full-stack apps, UI design, testing, and publishing - paste them into any AI assistant.

Full development guides are at [operator.livepeer.org/docs/guides/your-first-plugin](https://operator.livepeer.org/docs/guides/your-first-plugin). The SDK hooks reference is at [operator.livepeer.org/docs/api-reference/sdk-hooks](https://operator.livepeer.org/docs/api-reference/sdk-hooks).

<CustomDivider />

The [NaaP architecture](/v2/developers/build/plugins-and-extensions/naap-architecture) page covers the ShellContext interface and micro-frontend design in depth. The [NaaP tutorial](/v2/developers/build/tutorials/build-a-naap-plugin) walks through a complete plugin from scratch.
