The Scenario
You've built a React app — maybe a dashboard, a design tool, or a productivity suite. It has a free tier with basic functionality and a Pro tier with premium features. The code works, users are signing up, and now you need to actually gate those Pro features based on who's paying.
In the .NET world, you have dependency injection and server-side checks. In React, you need something different: a context provider that makes licensing available everywhere in your component tree, and client-side assertion evaluation against a verified authorization, so a check doesn't mean a round trip.
That's exactly what Monaiq's React SDK provides. Let's set it up.
Install the SDK
The React SDK is published on npm as @sidub-inc/licensing-client.
React is an optional peer dependency (16.8 or later), so the same package also runs in plain Node.
npm install @sidub-inc/licensing-client
That's it for dependencies. The SDK is TypeScript-first with full type definitions included — no separate
@types
package needed. If you're using JavaScript, the types are still there for editor IntelliSense.
Configure the Provider
Monaiq's React integration uses a context provider pattern — the same approach as React Router, Redux, or any
other library that shares state across your component tree. Wrap your app (or the section that needs licensing)
in a LicensingProvider:
import { LicensingProvider } from '@sidub-inc/licensing-client';
function App() {
return (
<LicensingProvider config={{
licenseServiceUri: 'https://api.monaiq.com/licensing',
encodedCredential: process.env.REACT_APP_LICENSE_CREDENTIAL
}}>
<YourApp />
</LicensingProvider>
);
}
The encodedCredential
is a SIDUB_LIC_...
license code, issued on a seat's page in the portal or returned by a completed purchase. It carries the seat id, a
runtime token scoped to that one seat, and the public key used for signature validation — all in one string, and no
account API key, so it is safe to ship.
The provider creates a LicensingClient
instance and makes it available to every component below via React context. The client is memoized — it only
recreates when your config actually changes.
Gate Features
Checking authorization is useful, but the real power is gating features. The client's
assertLicense
evaluates a license assertion against an authorization and returns a simple boolean.
import { useEffect, useState } from 'react';
import {
useLicensingContext,
ServiceAccessAssertion,
ServiceAccessLevel
} from '@sidub-inc/licensing-client';
import type { LicenseAuthorization } from '@sidub-inc/licensing-client';
function PremiumDashboard() {
const client = useLicensingContext();
const [authorization, setAuthorization] = useState<LicenseAuthorization | null>(null);
useEffect(() => {
client.getAuthorization().then(setAuthorization).catch(() => setAuthorization(null));
}, [client]);
const allows = (featureKey: string) =>
authorization !== null && client.assertLicense(
ServiceAccessAssertion.create(featureKey, ServiceAccessLevel.Allowed),
authorization
);
const hasAnalytics = allows('advanced-analytics');
const hasPdfExport = allows('pdf-export');
return (
<div>
{hasAnalytics ? <AnalyticsPanel /> : <UpgradeCard feature="Analytics" />}
{hasPdfExport ? <ExportButton /> : <UpgradeCard feature="PDF Export" />}
</div>
);
}ServiceAccessAssertion.create()
creates a typed assertion object. assertLicense
evaluates it against the authorization — entirely locally, with no network call. It returns
true or
false.
Repeated getAuthorization
calls are served from the client's cache, so gating per component is cheap.
This is the same assertion pattern used in the .NET SDK — ServiceAccessAssertion
checks for boolean access, RateLimitAssertion
handles rate-limited features, and QuotaAssertion
handles allowances. Same concepts, TypeScript API.
Track Usage
If your product includes consumption-based features — API calls, file exports, AI generations — you need to
report usage back to Monaiq. The client's
performOperation
method counts the use against the feature and, with
consumptionServiceUri: 'https://api.monaiq.com/consumption' in the provider's config, reports it to Monaiq:
import { useLicensingContext } from '@sidub-inc/licensing-client';
function ExportButton() {
const client = useLicensingContext();
const handleExport = async () => {
// Report the operation to Monaiq
await client.performOperation({
feature: { featureKey: 'pdf-export' },
operationType: 'increment',
quantity: 1,
timestamp: new Date()
});
// Then perform the actual export
await generatePdfExport();
};
return <button onClick={handleExport}>Export PDF</button>;
}
The useLicensingContext
hook gives you direct access to the LicensingClient
instance for imperative operations. Recorded usage appears in your analytics by feature, by customer and by offering,
and is billed for the period it happened in.
Next Steps
That covers the essentials: install, configure, authorize, gate, and track. You've gone from a React app with no licensing to one that enforces entitlements and reports usage — with about 30 lines of code.
From here, you can explore:
- Rate limiting — use
RateLimitAssertionfor time-windowed feature limits - Feature introspection — use
FeatureExistsAssertionto check if a feature exists in the authorization - Standalone client — construct
new LicensingClient(config)for non-React scenarios (e.g., utility scripts, Node.js backends) - In-app purchase — use
PurchaseClientto sell your offerings from an Electron, desktop or mobile shell - Product setup — define your products, offerings, and features in the Monaiq dashboard or via the MCP server
The React SDK uses the same Monaiq backend as the .NET SDK. If you're already using Monaiq for a server-side application, your products, offerings, and licenses work with the React client out of the box — no reconfiguration.
Check out the React SDK landing page for a full feature overview, or dive into the documentation for the complete API reference.
Ready to license your React app?
Create your free account and start enforcing in minutes.