Skip to main content
Migrate Already selling? Move your customers to Keylight without re-issuing a single key.
Keylight

Use case · Browser extensions

Licensing for browser extensions

Add paid tiers to your Chrome, Firefox, or Edge extension — Keylight's JavaScript SDK activates a key and gates Pro features, with no backend to build.

Start Free
Signed keys Pro unlocks Cross-browser

For developers selling paid Chrome, Firefox, or Edge extensions.

  • Stores take a cut or don't handle licensing at all.
  • You want Pro tiers without standing up a backend.
  • You need license checks that fit the extension runtime.

Updated June 2026

Browser extensions sit in a commercial grey zone: you have a real product, real users who get real value from it, and no reliable way to charge for it without building infrastructure the browser stores were never designed to provide. Chrome Web Store and Firefox Add-ons handle distribution — they don’t handle licensing. Adding a Pro tier means solving that yourself.

This page covers why browser extensions are worth monetising, what licensing looks like in that runtime, and how to implement it without a backend.

Why selling a paid browser extension is worth the effort

Most extension developers give their tools away for free, accept donations, or rely on the store’s built-in purchase system — which, on Chrome, was only recently made available to some developers, carries a 5% fee on top of payment processor costs, and gives you limited visibility into who your customers are.

The commercial case for a direct-licensed extension is straightforward: if your tool saves professionals half an hour a day, a one-time $29 or a $9/month Pro tier is a low-friction purchase. The friction isn’t on the buyer’s side — it’s on the developer’s side, because wiring up a license check in a service worker is non-obvious if you’ve never done it.

Direct licensing means you collect the customer’s email at purchase, you own the relationship, and you can communicate when you ship a new feature or a breaking change. You see who’s using what. You can offer renewal discounts, run promotions, and issue refunds without waiting for a store review. For extensions with a professional or business audience, the economics of direct distribution compare favourably to any alternative.

What licensing in a browser extension actually involves

A browser extension doesn’t run in a normal application environment. Background logic runs in a service worker (in Manifest V3 extensions) or a persistent background page (Manifest V2), and that context is more constrained than a native app in a few important ways.

Per-seat validation, not hard device-locking. On a native desktop app, the license system can bind to a stable hardware fingerprint — CPU serial, disk ID, or a platform credential store — so that one key can only activate on a fixed number of physical machines. A browser extension can’t do that reliably. The sandbox has no access to stable hardware identifiers, and storage (chrome.storage.local, localStorage, IndexedDB) can be cleared by the user or by the browser itself. This means Keylight is per-seat license validation in the extension context, not hard device-locking. One key, one user, one browser profile — that’s the right mental model. It’s still meaningful enforcement: a customer must enter a valid key before Pro features activate, and you can set per-key activation limits to discourage casual sharing. But be clear with yourself about what it is: you’re checking that a real, paid license was entered, not preventing someone who is determined to share their key from doing so. For most extension audiences, that’s the right tradeoff.

Storage strategy matters. Activation state needs to persist between browser sessions. The right store is chrome.storage.local (or the Firefox equivalent), which survives restarts and is not cleared by normal browser cache operations. The SDK call happens once at activation; subsequent launches read the stored state and revalidate periodically when online.

Service worker lifecycle. Manifest V3 service workers can terminate between events. Any setup code — including loading the keyset and checking activation state — needs to handle being re-run on each wake, or you need to cache results in chrome.storage.session for the current browser session.

Integrating with Keylight

// background.ts / service worker
import { Keylight, fetchKeyset, FetchTransport } from "@keylight-dev/js";

const ks = await fetchKeyset(new FetchTransport(), "https://api.keylight.dev", "your-tenant");

const kl = new Keylight({
  tenantId: "your-tenant",
  productId: "your-extension",
  sdkKey: "<your SDK key>",
  trustedKeys: ks?.keys ?? {},
});
await kl.load();

const res = await kl.activate("USER-LICENSE-KEY");
if (!res.activated) console.error(res.error);

if (kl.hasEntitlement("pro")) {
  // enable Pro features
}

The flow in practice: when a customer buys, Stripe fires the webhook to Keylight, which mints a signed key and emails it to the customer. They open your extension’s activation UI, paste the key, and your background script calls kl.activate(). The SDK validates the key against the keyset fetched from Keylight’s API, stores the result, and returns the entitlements.

Feature gating then works off kl.hasEntitlement("pro") — or whatever entitlements you defined on the product. The keyset is fetched once per service worker wake and cached; the signature check is local. No API call is required to gate features on subsequent openings once a valid lease is cached.

For the activation UI itself, you’ll typically build a small options page or popup with a license key input field. On submit, the popup messages the background service worker, which calls kl.activate() and reports back. Keep the activation logic in the background script — service workers have consistent access to chrome.storage and the network in a way that popup pages don’t.

Handling the extension lifecycle

A few patterns that matter specifically for extensions:

Revalidation. Call kl.load() on each service worker startup to reload cached state. If the cached lease is still fresh, no network round-trip happens. If a revalidation is due, the SDK checks in with Keylight’s API and updates the stored state. This is how revocations propagate: if a customer issues a chargeback, the key is marked revoked in Keylight, and the next revalidation returns an inactive state.

Popup → background communication. The extension’s popup and content scripts can’t call kl.hasEntitlement() directly — the SDK instance lives in the background. The clean pattern is a message-passing interface: the popup sends a getState message, the background responds with the current entitlement set, and the popup renders accordingly.

Per-key activation limits. Set an activation limit of 1 or 2 on your product in the Keylight dashboard. This means a given key can only be activated in a small number of browser profiles before the activation request is rejected. It’s a lightweight discouragement of key sharing, appropriate to the runtime.

Getting started

Set up a Keylight account, create a product, and connect your Stripe account. Install @keylight-dev/js in your extension project. Build the activation UI in your options page or popup, wire the background script to call kl.activate(), and test end-to-end with the free tier — which allows up to five licenses, enough to validate the full flow.

Keylight plans start at $19/month on the pricing page. For an extension with even a modest paid audience, the operational cost is well below the value of owning the customer relationship and not depending on a store’s licensing infrastructure.

The extension stores are excellent for distribution. For licensing, you’re better off owning it.

Frequently asked

Can I license a Chrome extension?+

Yes. The JavaScript SDK runs in your extension's background or service worker, activates the user's key, and gates Pro features on the returned entitlements.

How strong is device-binding in a browser extension?+

Lighter than on desktop. The browser sandbox has no stable hardware fingerprint and storage can be cleared, so treat Keylight as per-seat license validation rather than hard device-locking.

Start licensing your app today

Drop in the Swift SDK, point it at your dashboard, and sell paid apps in under a minute. Free forever tier included.

Start Free