@extport/sdk
License activation and anonymous usage analytics for browser extensions publishing through extport — sell lifetime licenses through your own Stripe Payment Link and see active users across Chrome, Firefox, Edge, and Safari in one dashboard.
The server is the only source of truth: activations verify online and cache the resulting entitlement locally. There is deliberately no client-side cryptography to reverse-engineer.
Install
Section titled “Install”pnpm add @extport/sdkLicensing
Section titled “Licensing”// lib/activation.ts — shared by every contextimport { createActivationClient } from '@extport/sdk'import { webextTransport } from '@extport/sdk/webext'
interface PlanLimit { records: number}
const plans: Record<'free' | 'pro', PlanLimit> = { free: { records: 100 }, pro: { records: Number.MAX_SAFE_INTEGER },}
export const activationClient = createActivationClient<'free' | 'pro', PlanLimit>({ plans, transport: webextTransport(),})extensionId resolves automatically when the extension is built with @extport/wxt (extport: { extension: 'ext_…' }); otherwise pass it explicitly.
// Redeem a code the buyer received by emailawait activationClient.activate('XXXX-XXXX-XXXX-XXXX')
// Gate a feature — always reads current persisted stateconst plan = await activationClient.getPlan()if (count > plan.limit.records) showUpgradePrompt()
// Periodic heartbeat + self-healing re-activation (call from the background)await activationClient.checkActivation()React rendering layer:
import { usePlan } from '@extport/sdk/react'
function Paywall() { const plan = usePlan(activationClient) return plan.tier === 'pro' ? <ProBadge /> : <UpgradeButton />}Guide: docs.extport.dev/licensing
Analytics
Section titled “Analytics”One anonymous ping per install per day — a random install id, version, and browser UI language; browser, OS, and country derive server-side from the request. No URLs, no page content, no behavioral data.
import { attachAnalytics } from '@extport/sdk/analytics'
attachAnalytics() // extensionId auto-resolves via @extport/wxt, or pass { extensionId: 'ext_…' }With @extport/wxt this is a single config flag (analytics: true) instead. Firefox’s built-in data-collection consent (technicalAndInteraction) is respected automatically. A provider for @wxt-dev/analytics ships as @extport/sdk/wxt-analytics.
Guide: docs.extport.dev/analytics
License
Section titled “License”MIT