The Plugin SDK (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/rivenmedia/riven-ts/llms.txt
Use this file to discover all available pages before exploring further.
@repo/util-plugin-sdk) is the TypeScript package that every Riven integration is built on. Whether you are connecting a new content source, wiring up a metadata provider, scraping a torrent index, or adding subtitle support, you express that integration as a plugin that implements the RivenPlugin interface and is registered at application startup. Once registered, Riven provisions each plugin’s own BullMQ queues, injects dependencies into GraphQL resolvers at request time, and routes typed events to the hook handlers the plugin declares.
The SDK is not yet published to npm. Plugins live inside the monorepo as workspace packages under
packages/plugin-<name>. Community distribution via npm is planned for a future release.The RivenPlugin interface
Every plugin exports a single named plugin constant that satisfies the RivenPlugin type. The SDK validates the shape at startup using Zod, so mismatches are caught before any handler fires.
Plugins retrieve their configuration by calling
settings.get(YourSettingsSchema) — never by reading process.env directly. The registrar strips plugin environment variables out of the environment before importing any plugin module, so one plugin cannot read another plugin’s secrets.Six extension points
Each key ofRivenPlugin maps to a distinct extension point. You only need to implement the ones relevant to your plugin type.
DataSources
Subclass
BaseDataSource to wrap an HTTP API. You get BullMQ-backed request queuing, configurable rate limiting, automatic retry with exponential back-off, response caching, and OpenTelemetry tracing — all without writing any infrastructure code. Instances are injected into resolvers via the @PluginDataSource() decorator.GraphQL Resolvers
Register
type-graphql resolver classes in the resolvers array. Each plugin must provide at least one resolver. Use the @PluginDataSource() parameter decorator to receive a DataSource instance scoped to the current plugin. A settings resolver extending the global Settings type lets clients discover available configuration keys.Event Hooks
Declare handlers in the
hooks object keyed by event type string. Each handler receives a { dataSources, settings, event } context and must return the expected payload shape. The SDK enforces handler signatures with Zod function schemas at startup, not at call time.Settings Schema
A
ZodObject passed as settingsSchema. Riven parses the plugin’s prefixed environment variables through this schema at registration time, applies defaults, and freezes the result. Fields annotated with .describe() are included in the generated settings documentation.Context Factory
The optional
context function runs once per request before resolvers execute. It receives the fully-initialised PluginContext and returns an additional Record<string, unknown> that is merged into the Apollo GraphQL context under the plugin’s Symbol key — useful for per-request state that multiple resolvers share.Validator
The
validator function is called during startup, after DataSources are initialised but before the plugin is marked as valid. It receives a fully-populated PluginContext with access to DataSources and settings. Return true to mark the plugin healthy, false to mark it invalid without crashing the rest of the application.Plugin lifecycle
Understanding the order in which Riven initialises a plugin helps you write reliable validators and avoid accessing uninitialised dependencies.Registration
At startup,
apps/riven imports each plugin package and reads its exported plugin constant. The Zod schema for RivenPlugin validates the shape immediately.Settings parsing
PluginSettings reads all RIVEN_PLUGIN_SETTING__<prefix>__<key> environment variables prefixed for this plugin, parses them through settingsSchema, applies defaults, and removes the variables from process.env.DataSource initialisation
Each class listed in
dataSources is instantiated with the parsed settings, a Redis connection, an HTTP cache adapter (Keyv/Redis), the plugin Symbol, and telemetry hooks. The BullMQ Queue, QueueEvents, and Worker are started immediately.Validation
The
validator function is called with a PluginContext containing the live DataSource instances and the frozen settings. Returning false marks the plugin invalid; the plugin’s queues remain up, but no events will be dispatched to it.Hook worker registration
For every key declared in
hooks, Riven creates a dedicated BullMQ worker subscribed to that event type. Each worker runs the handler and publishes the result as a new downstream event.What the SDK exports
The package exports everything a plugin author needs from a single entry point (@repo/util-plugin-sdk) plus a set of sub-path exports for DTOs and utilities.
BaseDataSource and HTTP utilities
BaseDataSource and HTTP utilities
BaseDataSource<TSettings> — abstract class extending Apollo’s RESTDataSource with the BullMQ request pipeline built in. Override baseURL, serviceName, rateLimiterOptions, willSendRequest, and validate. Export RateLimiterOptions (re-exported from bullmq) to type the rate-limiter config.Decorators
Decorators
Two GraphQL parameter decorators are exported from
@repo/util-plugin-sdk:PluginContext(symbol)— injects the full plugin context object stored under the given Symbol in the Apollo context.PluginDataSource(symbol, DataSourceClass)— resolvesdataSources.get(DataSourceClass)from the plugin context and injects the live instance.
Schema types and validators
Schema types and validators
RivenPlugin— Zod schema and inferred TypeScript type for the plugin manifest.RivenPluginConfig— minimal config object ({ name: symbol }).DataSourceConstructor— interface for a BaseDataSource constructor.DataSourceMap— typedMap-like class keyed by constructor, used inside PluginContext.PluginSettings— the parsed, frozen settings store.
DTO entities
DTO entities
All MikroORM entities and their associated GraphQL types are available under the
/dto/entities sub-path export:Movie,Show,Season,Episode— core media item hierarchyMediaItem— union base typeStream,BlacklistedStream— torrent stream recordsFilesystemEntry,MediaEntry,SubtitleEntry— VFS path objectsItemRequest— user content request record
Event schemas and handler types
Event schemas and handler types
All typed event schemas live in the The complete set of event keys available as hook keys is listed in the Events reference.
@repo/util-plugin-sdk/events sub-path export. Import handler types to annotate hook functions:Validation utilities
Validation utilities
atLeastOnePropertyRequired— Zod refinement that rejects objects with all-undefined values.recordIsNotEmpty— Zod refinement that rejects empty record objects.
Plugin categories
Riven’s event model is flexible enough to support a wide range of plugin types. The sameRivenPlugin interface covers all of them — which hooks you declare determines what role the plugin plays.
| Plugin type | Primary hook(s) | Example |
|---|---|---|
| Content source | riven.content-service.requested | Seerr, MDBList, Listrr |
| Metadata provider | riven.media-item.index.requested.movie, .show | TVDB, TMDB |
| Scraper | riven.media-item.scrape.requested | Comet, Torrentio |
| Downloader | riven.media-item.download.requested | StremThru |
| Stream-link provider | riven.media-item.stream-link.requested | Debrid proxies |
| Subtitle provider | riven.media-item.subtitle.requested | SubDL |
| Media server | riven.core.started, riven.media-item.index.success | Plex, Jellyfin |
| Notification service | Various success/error events | Custom webhook plugin |
Next steps
Quickstart
Scaffold your first plugin with the Turborepo generator and have it running in minutes
Building a DataSource
Deep dive into BaseDataSource: rate limiting, caching, retry logic, and willSendRequest
GraphQL Resolvers
Wire up type-graphql resolvers and inject DataSources with the PluginDataSource decorator
Event Hooks
Subscribe to the full event catalogue and return typed payloads