Plugin architecture
Sellub’s server is a Vendure application; almost every Sellub-specific
behaviour ships as a Vendure plugin under
apps/sellub/sellub-server/src/plugins/. This page is the canonical map of
those plugins, what they own, and how they relate.
Naming convention. New, Sellub-owned plugins use the
sellub-*prefix. A small handful of older or “library-flavoured” plugins keep their original names (multivendor-plugin,marketplace-shop-plugin,seller-profile-plugin,admin-customer-plugin,inventory-sync-plugin,arkesel-sms-plugin). All future plugins should use the prefix.
At a glance
| Plugin | Purpose | Owns custom fields |
|---|---|---|
sellub-core | Shared utilities, channel guards, RBAC primitives | — |
sellub-api-keys | Channel-scoped publishable/secret keys; embed sessions | Channel.sellubApiKeys, etc. |
sellub-pricing-plugin | Persists OrderFeeBreakdown; commission/processor math | Seller.sellerPlan, etc. |
sellub-commerce-api-plugin | Plan subscriptions, sandbox channels, API usage logs, webhooks | Channel.sellubIsSandbox, etc. |
sellub-event-bridge | Forwards Vendure events to DPS (dps_vendure_event cloud function) | — |
sellub-payment | Paystack integration (handler + webhook controller) | — |
sellub-external-payments | One-shot payments outside the cart (donations, hosted invoices) | — |
sellub-subscriptions | Recurring billing primitives (Paystack subs) | — |
sellub-billing | Operator-facing billing (invoicing platform fees) | — |
sellub-delivery | Wrapper that registers the delivery base plugin | — |
sellub-delivery-base | Local-courier delivery method, address validation, dispatch hooks | Order.deliveryQuote |
sellub-fulfilment | Vendure fulfilment handler glue | — |
sellub-freight | International / multi-leg freight quoting | (planned) |
sellub-print | Print-on-demand product type and POD partner adapters | (planned) |
sellub-services | Time-bookable services (lessons, consultations) | (planned) |
sellub-bundles | Bundle/composite products | (planned) |
sellub-social | Social-graph product surfacing (likes, follows, sharing hooks) | (planned) |
multivendor-plugin | Marketplace channel-per-seller scaffolding | various seller fields |
marketplace-shop-plugin | Aggregated marketplace shop API (cross-channel listings) | — |
seller-profile-plugin | Seller public profile resolver + admin mutations | various seller fields |
admin-customer-plugin | Admin-side customer management extensions | — |
inventory-sync-plugin | Cross-channel stock sync, partner inventory webhooks | (planned) |
arkesel-sms-plugin | Arkesel SMS provider for Vendure notifications | — |
Layering
Vendure core
│
┌────────────┼────────────┐
│ │ │
sellub-core multivendor admin-customer
│
┌────────────┼────────────────────────┐
│ │ │
sellub- sellub- sellub-
api-keys pricing-plugin commerce-api-plugin
│ │
└────► sellub-event-bridge ────► DPS
sellub-payment ──► sellub-external-payments
└─► sellub-subscriptions ──► sellub-billing
sellub-delivery ──► sellub-delivery-base
sellub-fulfilment
sellub-freight, sellub-print, sellub-services,
sellub-bundles, sellub-social (vertical product types)
marketplace-shop-plugin, seller-profile-plugin (storefront/admin views)
inventory-sync-plugin (sync glue)
arkesel-sms-plugin (notifications)When to add a new plugin
Create one when any of these are true:
- You’re introducing a new product type (freight, services, bundles, etc.).
- You need new custom fields on a Vendure entity.
- You’re integrating a new third-party provider (payments, courier, SMS).
- You’re forwarding events to a system outside the Vendure DB.
Otherwise, extend an existing plugin.
Plugin authoring rules
- One plugin = one concern. Don’t bolt sandbox-channel logic into
sellub-payment; that’ssellub-commerce-api-plugin’s job. - Channel-aware by default. Resolvers must enforce the active channel;
see
sellub-core/RequireSellubChannel. - No DPS imports in plugins other than
sellub-event-bridge. Other plugins talk to DPS via Vendure events that the bridge forwards. - Custom fields live with their owning plugin. The plugin that reads a field also declares it.
- Admin GraphQL ≠ Shop GraphQL. Operator features go on Admin; storefront features go on Shop. Don’t mix.
- READMEs are required. Every
src/plugins/*directory has aREADME.mddescribing scope, custom fields, GraphQL surface and env vars.
Deprecated / removed plugins
| Removed plugin | Replaced by | Notes |
|---|---|---|
dps-e-* | sellub-* equivalents (Path B, May 2026) | Renamed in place; same code |
dps-delivery-plugin | sellub-delivery-base | Restored from git history |
dps-event-bridge | sellub-event-bridge | Restored from git history |
16× @duabalabs/sellub-vendure-* npm packages | (none — internal only) | Deprecated on npm + deleted on GitHub on 2026-05-11 |