grafana/grafana
Plugin host
The plugin host is responsible for discovering, loading, sandboxing, and dispatching to plugins. It lives across two trees:
pkg/plugins/— the core host (manager, loader, registry, gRPC dispatch).pkg/services/pluginsintegration/— DI glue, lifecycle, and integration with the rest of the server.
Plugin types
Grafana supports three flavors of plugins:
- Datasource plugin — provides a
DataSourceclass (frontend) and optionally aDataSourceServer(backend). Returns DataFrames. - Panel plugin — frontend-only React component that renders a panel.
- App plugin — bundles UI pages, custom routes, and may also include datasource/panel plugins.
A plugin can have:
- A frontend module (TypeScript, bundled to
module.js) — required for datasource and panel; optional for app. - A backend binary (Go using
grafana-plugin-sdk-go) — required for datasource plugins that need server-side execution.
Layout
pkg/plugins/
├── plugins.go # Plugin model + interfaces
├── manager/ # Lifecycle: install, start, stop, register
├── loader/ # Discover & verify on disk
├── repo/ # grafana.com plugin repository client
├── pipeline/ # Plugin loading pipeline (steps)
├── pfs/ # Plugin filesystem abstraction
├── plugindef/ # plugin.json schema + decoder
├── backendplugin/ # gRPC client to subprocess plugins
├── envvars/ # Per-plugin env var injection
├── auth/ # Plugin auth helpers
├── log/ # Plugin log capture
├── oauth/ # OAuth token forwarding to plugins
├── plugincontext/ # Per-request context passed into plugins
├── storage/ # Plugin disk paths
└── manager/sources/ # Bundled, gcom, registry sourcesThe companion DI layer:
pkg/services/pluginsintegration/
├── plugins.go # Wire-friendly aggregator
├── plugincontext/ # ReqContext → PluginContext
├── pluginerrs/ # Error types
├── pluginchecker/ # Periodic update checks
├── pluginsettings/ # Per-org plugin settings
├── pluginstore/ # Plugin registry storage
├── adapters/ # Adapt new SDK to old internal interfaces
└── ... (~30 sub-packages)Lifecycle
graph TD
Boot[Server start] --> Discover[loader<br/>scan disk + registry]
Discover --> Verify[Signature & manifest verify]
Verify --> Register[manager<br/>Register in store]
Register --> Backend[Start backend subprocess<br/>if any]
Backend --> gRPC[Open gRPC channel]
gRPC --> Ready[Plugin ready]
Request[Datasource query] --> Dispatch[manager.Dispatch]
Dispatch --> Lookup[Lookup plugin by id]
Lookup --> Forward[Forward gRPC call]
Forward --> Plugin[Plugin process]
Plugin --> Forward
Forward --> Response[Response back to client]Bundled plugins (public/app/plugins/datasource/*, public/app/plugins/panel/*, and the matching pkg/tsdb/<name>/) are registered as in-process plugins; their backend "subprocess" is just a Go function call.
External plugins discovered in data/plugins/ (or wherever [plugins] plugins_path points) are launched as separate processes that communicate over gRPC. The plugin host enforces signature verification per [plugins] allow_loading_unsigned_plugins.
Frontend loading
The frontend has its own loader in public/app/features/plugins/:
plugin_loader.tsresolves a plugin'smodule.jsand runs it.pluginPreloader.tswarms up apps markedauto_enabled_apps.sandbox/runs untrusted plugin code inside an iframe with a restricted DOM API. Toggleable via thepluginsFrontendSandboxfeature flag.- The dynamic
import()of a plugin returns its exportedPluginobject (new DataSourcePlugin(...).setQueryEditor(...).setConfigEditor(...)).
Plugin context
Each call into a plugin receives a PluginContext (pkg/plugins/plugincontext/) carrying:
- The user identity (
user.SignedInUser). - The datasource instance settings (URL, jsonData, decrypted secureJsonData).
- The plugin instance settings (per-org
pluginsettings). - A request scope (orgID, requestID).
Backend plugins use this to authenticate to upstream systems (e.g. inject the configured Bearer token) and to scope responses.
Error handling
Plugin failures are first-class — errors are wrapped with pluginerrs types and surfaced to the UI as red error banners on panels. Common failure modes:
signature: invalid— failed signature check.dependency: missing— plugin requires a Grafana version > installed.- Backend
rpc error— subprocess crashed or didn't respond.
The plugin admin UI (public/app/features/plugins/admin/) shows install/update/error state per plugin.
Update checks
pkg/services/pluginsintegration/pluginchecker/ periodically queries grafana.com for new versions of installed plugins. The "Updates" tab in the plugins UI is driven by this.
Key source files
| File | Purpose |
|---|---|
pkg/plugins/plugins.go |
Core plugin types |
pkg/plugins/manager/manager.go |
Plugin lifecycle |
pkg/plugins/loader/loader.go |
Discovery + load pipeline |
pkg/plugins/backendplugin/ |
gRPC dispatch |
pkg/plugins/plugindef/ |
plugin.json schema |
pkg/services/pluginsintegration/plugins.go |
DI aggregator |
public/app/features/plugins/plugin_loader.ts |
Frontend loader |
public/app/features/plugins/sandbox/ |
iframe sandbox |
See also
- Datasources & queries — how plugins are invoked.
- TSDB query backends — built-in datasource backends.
- Built-in plugins — the panel and datasource plugins shipped with Grafana.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.