How to Make Money Selling Plugins and Themes on ShopsWired
You sell ecommerce plugins on ShopsWired by building a plugin or theme with the local CLI, marking paid code as private, setting a price (one-time, monthly subscription, or tiered plans), and publishing it to the built-in Marketplace. Merchants install it from inside their admin, ShopsWired handles billing, and you keep 70% of every paid invoice, paid out automatically through Stripe Connect.
If you already write JavaScript, the barrier to a first sale is low: no separate app-store account, no review-and-resubmit cycle for every change, and no infrastructure to run. This guide covers what actually sells, the publishing flow end to end, and how to price for recurring revenue instead of one-off downloads.
Why build for ShopsWired
ShopsWired is a fully managed commerce platform — a Shopify alternative with 0% platform transaction fees and simple per-shop pricing. Every store ships with a built-in app store that has Featured, Themes, and Plugins sections, search, and per-item detail pages with README, versions, and pricing. That means distribution is solved: your listing sits one click from every merchant who needs it, and installs, updates, and billing all run through the same admin they already use.
Two things make it developer-friendly. First, plugins are plain modern JavaScript running on ShopScript, ShopsWired's server-side JavaScript runtime — you hook storefront events, define routes, add dashboard widgets, and talk to the database through provided bridges, all in ES2015+. Second, you build against a real shop with instant live preview, so the feedback loop is your editor, not an upload queue.
What actually sells
The best-selling extensions solve a concrete merchant job that the platform doesn't do natively. Before you build, read the native features reference so you don't rebuild something merchants already have. Categories that consistently have demand:
- Integrations — sync orders, inventory, or customers to an external ERP, accounting tool, marketing platform, or shipping service. These are sticky and naturally subscription-priced.
- Payment and gateway apps — connect a processor the merchant needs, with its own webhook setup.
- Storefront enhancements — product reviews, wishlists, back-in-stock alerts, upsell widgets, custom search providers.
- Operations automation — scheduled jobs that reindex catalogs, dedupe records, generate feeds, or run nightly exports.
- Themes — polished, niche-specific storefront designs. Merchants can preview a marketplace theme live on desktop and mobile before installing, so a strong preview sells the theme.
A useful heuristic: if the feature saves a merchant a recurring hour or connects them to a system they already pay for, it justifies a monthly price. If it's a one-time cosmetic change, price it as a one-time unlock.
Build it locally with the CLI
Development happens on your machine against a live shop. Enable Developer Mode on the target store (Settings → Developer), then use the shopswired CLI:
shopswired login # secure device auth, no passwords in the terminal
shopswired link # pick which shop to develop against
shopswired dev # serve local files with instant live previewA minimal plugin is a directory with a manifest.json and one or more scripts:
{
"id": "my_plugin",
"name": "My Plugin",
"version": "1.0.0",
"scripts": [
{ "path": "hooks.js" }
]
}Hook names are auto-detected from each script's module.exports, and every handler receives ctx as its first argument. When the plugin is ready, install it permanently to the shop:
shopswired push --type plugin --id my-plugin
shopswired push --type theme --id my-themeFull command reference and the manifest schema live in the developer docs.
Protect paid code
By default a plugin is open-source — any shop that installs it can pull, view, and copy every file. That's great for free, community plugins, but not for something you charge for. To ship proprietary code, add one key to the manifest:
{
"id": "my_plugin",
"name": "My Plugin",
"version": "1.0.0",
"source": "private",
"scripts": [
{ "path": "hooks.js" }
]
}With "source": "private", the platform refuses to serve your files to anyone but you. Installed shops still run the plugin normally — hooks, routes, widgets, and scheduled jobs all execute — and configure its settings; they just can't download or read the source.
Price for recurring revenue
Free items install directly. Paid items support a one-time purchase, a monthly subscription, or tiered plans. Subscriptions are where the compounding revenue lives, and ShopsWired makes tiers a manifest concern:
{
"id": "my_plugin",
"name": "My Plugin",
"version": "1.0.0",
"plans": ["free", "pro", "biz"]
}You declare only the ordered plan keys. The price, display name, billing interval, and feature list are filled in at publish time in the Publish dialog and stored on the listing — so prices stay out of your source and you can re-price without shipping code. Each tier can be free, one_time, or subscription (monthly), and a $0 keyed tier is allowed for a free-but-tracked plan.
Your code reads the active tier from ctx.plan and gates features accordingly:
module.exports.hook_product_save = (ctx) => {
if (ctx.plan === 'biz') {
// business-tier feature
} else if (ctx.plan) {
// any selected paid/keyed plan (pro, hobby, ...)
} else {
// '' -> no plan selected, or a plugin with no plans
}
}Gate anything billable on the server-side key — never trust a client-side check. Shops upgrade and downgrade between subscription tiers in-app, and Stripe prorates the change automatically.
In-app purchases for usage-based add-ons
Beyond the plan tier, a plugin can sell in-app purchases after install — a one-time unlock or a pack of consumable credits (AI tokens, SMS sends, and the like). Declare the catalog in the manifest, then request a purchase at runtime; the merchant always sees the exact charge and must approve it before anything is billed:
const res = sw.iap.requestPurchase({
product: "credits",
amount: 2000, // cents, shown and charged on approval
credits: 1000,
description: "1,000 Action Credits",
});
// later, spend a credit safely:
const left = sw.iap.consume({ key: "credits", amount: 1, idempotencyKey: "send-" + msgId });There's no silent-charge path — requestPurchase mints a signed token and the owner approves it on a native approval screen. In-app purchases work for free and paid plugins alike, so a free plugin can still generate revenue from usage.
Publish and get paid
To sell, connect a Stripe account under the shop's Developer settings, then publish your plugin or theme with a price. From there:
- Merchants find and install your listing from their built-in app store; paid items charge through their existing ShopsWired invoice.
- You're paid 70% of each paid invoice, transferred automatically via Stripe Connect (a platform fee covers the rest). The same rails handle plan subscriptions, one-time purchases, and in-app purchases.
- The author shown on the marketplace card is your publishing shop's name, so pick a shop name that reads as your brand.
Because updates flow through the same install-and-version system, you ship a new version and merchants apply it from their admin — no per-release approval gauntlet.
A pragmatic path to your first sale
Start with one narrow, high-value integration or a themed storefront for a niche you know. Build it against your own dev shop, mark the code private, and publish it as a low monthly subscription rather than a one-time fee — recurring revenue from ten installs beats a handful of one-off downloads. Then let usage tell you where the next tier or in-app credit pack belongs.
The cheapest way to get a real shop to build and test against is the current promotion: Pro at $1/month for the first three months. Spin up a store, enable Developer Mode, and start pushing code today.
← Back to Blog