← All notes
April 26, 2026hermespluginsarchitecturereactEdit on GitHub →
# Hermes plugin architecture

Every Hermes dashboard plugin is **four files**:

```
my-plugin/
└── dashboard/
    ├── manifest.json       # metadata
    ├── plugin_api.py       # FastAPI router
    └── dist/
        └── index.js        # React component (no build step)
```

Drop the folder into `~/.hermes/plugins/`, restart the dashboard, done.

## Manifest — what it controls

```json
{
  "name": "credits",          // URL slug → /api/plugins/credits/...
  "label": "Credits",          // sidebar text
  "description": "...",        // shown in registries
  "icon": "Wallet",            // any lucide-react name
  "version": "1.0.0",
  "tab":   { "path": "/credits", "position": "end" },
  "slots": ["analytics:top"],  // where to inject widgets
  "entry": "dist/index.js",
  "api":   "plugin_api.py"
}
```

Three placement modes:

1. **Tab page** — `tab.path` set; sidebar entry rendered; `register(name, Component)` provides the page.
2. **Slot widget** — `slots: [...]` set; injected into existing dashboard pages without owning a route. Use `registerSlot(name, slotName, Component)`.
3. **Both** — useful when a small slot widget links into a larger detail page.

## SDK surface (frontend)

```js
const SDK = window.__HERMES_PLUGIN_SDK__;
const { React, hooks, components, fetchJSON, utils, api } = SDK;
const { useState, useEffect, useCallback, useMemo } = hooks;
const { Card, CardHeader, Button, Badge, Input, Select } = components;
```

- **No build step.** Plain IIFE that reads window globals. Edit and reload.
- **fetchJSON** auto-includes the dashboard session token.
- **components** are shadcn/ui primitives, themed by the active dashboard theme.

## Backend (FastAPI)

```python
from fastapi import APIRouter
router = APIRouter()

@router.get("/status")
async def status():
    return {"ok": True}
```

Routes mount at `/api/plugins/<manifest.name>/<route>`. Standard FastAPI — async, dependency injection, the lot.

## Known slots

| Slot | Where |
|---|---|
| `analytics:top` | Top of /analytics |
| `sessions:top` | Top of /sessions |
| `cron:top` | Top of /cron |
| `header-right`, `header-banner` | Global chrome |
| `sidebar` | Below main nav |
| `pre-main`, `post-main` | Wrap the main column |

## What this unlocks

- **Three-file plugins** for cost/quota widgets, status indicators, custom config panels.
- **Slot-only plugins** — no new tab, just add a card to an existing page (e.g. credits widget on Analytics).
- **Hot iteration** — edit `dist/index.js`, hard-refresh the dashboard tab, see the change.
- **Independent versioning** — each plugin is its own git repo, semver-bumped, installable via `git clone`.

## See also

- The `hermes-plugin-template` repo: github.com/Atemndobs/hermes-plugin-template
- The credits plugin (real-world example): github.com/Atemndobs/hermes-plugin-credits
- The hub that auto-indexes them: hermes-plugins-hub.vercel.app
Hermes plugin architecture — manifest, API, frontend, slot · Notes