Skip to Content
🚀 We just launched! Please star us on Github!
DocumentationPluginsBuilding Extensions

Building Extensions

Smart Panel supports a plugin architecture that lets you extend both the backend (NestJS) and the admin UI (Vue.js) with custom functionality. Extensions are distributed as npm packages.


Overview

An extension is an npm package that declares one or both of these manifests in its package.json:

  • fastybird.smartPanelBackend — a NestJS module mounted at a route prefix
  • fastybird.smartPanelAdmin — a Vue 3 plugin loaded into the admin interface

Smart Panel discovers installed extensions automatically by scanning node_modules for packages with these manifests.


Quick Start

The easiest way to get started is to use the example extension as a template.

Clone the example

The packages/example-extension/ directory in the Smart Panel repository contains a fully working extension with both backend and admin components.

cp -r packages/example-extension my-extension cd my-extension

Package manifest

Your package.json must include the fastybird field with your extension manifests:

{ "name": "@my-org/my-extension", "version": "1.0.0", "fastybird": { "smartPanelBackend": { "kind": "plugin", "routePrefix": "my-extension", "extensionExport": "MyExtensionModule" }, "smartPanelAdmin": { "kind": "plugin", "extensionEntry": "admin/index.js" } } }

The kind field can be "module" or "plugin". Modules are mounted at /api/<routePrefix>, while plugins are mounted at /api/plugins/<routePrefix>.


Backend Extension

A backend extension is a standard NestJS module. It can define controllers, services, and entities just like any other module in the system.

Module definition

import { Module, OnModuleInit } from '@nestjs/common'; import { MyController } from './my.controller'; import { MyService } from './my.service'; @Module({ controllers: [MyController], providers: [MyService], }) export class MyExtensionModule implements OnModuleInit { onModuleInit() { console.log('My extension loaded'); } }

Controller

import { Controller, Get } from '@nestjs/common'; import { ApiExcludeController } from '@nestjs/swagger'; @ApiExcludeController() @Controller() export class MyController { @Get('status') getStatus() { return { name: 'my-extension', ok: true, timestamp: new Date().toISOString(), }; } }

With routePrefix: "my-extension" and kind: "plugin", this endpoint will be available at GET /api/plugins/my-extension/status.

Configuration DTO

Extensions can accept configuration through the plugin config system:

import { IsBoolean, IsOptional } from 'class-validator'; import { UpdatePluginConfigDto } from '@fastybird/smart-panel-backend'; export class MyConfigDto extends UpdatePluginConfigDto { @IsOptional() @IsBoolean() enabled?: boolean; }

Admin Extension

An admin extension is a Vue 3 plugin that gets installed into the admin application.

Plugin entry point

Create an assets/index.ts file (or wherever your extensionEntry points after build):

import type { App } from 'vue'; export default { install(app: App) { // Register components, routes, or provide services // app.component('MyWidget', MyWidget); }, };

Build configuration

Use Vite to build the admin entry as an ESM library:

// vite.config.ts import { defineConfig } from 'vite'; export default defineConfig({ build: { lib: { entry: 'assets/index.ts', formats: ['es'], fileName: 'index', }, outDir: 'admin', rollupOptions: { external: ['vue'], }, }, });

Manifest Reference

Backend manifest (fastybird.smartPanelBackend)

FieldTypeRequiredDescription
kind"module" | "plugin"YesRoute mounting strategy
routePrefixstringYesURL path segment(s)
extensionExportstringYesNamed export of the NestJS module class
sdkVersionstringNoCompatible SDK version
displayNamestringNoHuman-readable name
descriptionstringNoShort description

Admin manifest (fastybird.smartPanelAdmin)

FieldTypeRequiredDescription
kind"module" | "plugin"YesPlugin type
importPathstringNoModule specifier for static import
extensionExportstringNoNamed export (if not using default export)
extensionEntrystringNoESM entry point for runtime loading
sdkVersionstringNoCompatible SDK version
displayNamestringNoHuman-readable name
descriptionstringNoShort description

Installing Your Extension

Once published to npm (or a private registry), install it into your Smart Panel:

npm install @my-org/my-extension

Restart the backend and the extension will be discovered and loaded automatically.

💡

For local development, you can use npm link or a pnpm workspace to link your extension package directly.


What’s Next?

Last updated on