All posts

How to set up license keys in an Electron application

Nicholas Affonso

December 19, 2025

How to set up license keys in an Electron application

Paid Electron apps need a secure way to block unauthorized access, often with license keys. In this guide, you'll integrate Keyforge into an Electron application for reliable licensing.

You'll also see how to set up payments via Stripe, Lemon Squeezy, or Polar, and how to support offline license verifications using the Keyforge client SDK.

Before you start

Make sure you've created the basics inside your Keyforge account:

Activating a license

When a user first opens your app, prompt them to enter their license key. Then, send that key to Keyforge to activate it on the user's device.

import { machineId } from 'node-machine-id';
import os from 'os';

const res = await fetch(
  'https://keyforge.dev/api/v1/public/licenses/activate',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      licenseKey: 'ABCDE-ABCDE-ABCDE-ABCDE-ABCDE',
      deviceIdentifier: await machineId(),
      deviceName: os.hostname(),
      productId: 'p_123456',
    }),
  }
);

const data = await res.json();
console.log('License activated');

Device identifier

A common way to get a unique device identifier in Electron apps is to use the node-machine-id package. You can also use a persistently stored UUID, or any other unique identifier for the device.

After activation, store the license key locally so it can be used for future verifications.

Validating a license

Your app should validate the license key on each launch to ensure it's still valid. Use the Keyforge API to check the license status. This call can also be made periodically, such as every few hours.

import { machineId } from 'node-machine-id';

const res = await fetch(
  'https://keyforge.dev/api/v1/public/licenses/validate',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      licenseKey: 'ABCDE-ABCDE-ABCDE-ABCDE-ABCDE',
      deviceIdentifier: await machineId(),
      productId: 'p_123456',
    }),
  }
);

const data = await res.json();
if (data.isValid) {
  console.log('License is valid');
} else {
  console.log('License invalid');
}

If Keyforge indicates the license is invalid, prompt the user to re-enter their license key.


Payments and customer portal

Connect a payment provider to automatically generate and deliver a license key by email whenever someone buys your app, with no backend or webhooks required. Keyforge supports Stripe, Lemon Squeezy, and Polar for both one-time purchases and subscriptions.

For subscriptions, license expiration dates update automatically on each renewal, and the license is deactivated if a subscription is cancelled. Follow the payments setup guide to connect your product. Customers can manage their licenses, devices, and billing through the customer portal.

License upgrades and renewals

You can offer customers the option to upgrade their license to a higher tier or extend the expiration date of a timed license, directly from the customer portal with no code required. Configure up to 3 upgrade or renewal options per product in the dashboard.

Perpetual fallback

Perpetual fallback lets customers keep using your app with limited functionality after their license expires, rather than being locked out entirely. When enabled on a product, the validate endpoint returns status: "fallbacked" for expired licenses.

const data = await res.json();

if (data.status === 'active') {
  // Full access
} else if (data.status === 'fallbacked') {
  // License expired - grant limited access based on your product's logic
  console.log('Running in limited mode');
} else {
  // Invalid - prompt the user to re-enter their license key
}

You decide how to limit functionality, for example, disabling access to new updates while keeping core features available.


Offline licensing

If your Electron app needs to run in environments without constant internet access, you can use the license tokens feature. These are signed JWTs that your app can verify locally using the Keyforge client SDK.

When license tokens are enabled for a product, the activation response includes a token field. Use activateLicense from the SDK to activate and retrieve the token in one step, then store it for offline use.

import { activateLicense } from '@keyforge/client';
import { machineId } from 'node-machine-id';
import os from 'os';

const { token } = await activateLicense({
  licenseKey: 'ABCDE-ABCDE-ABCDE-ABCDE-ABCDE',
  deviceIdentifier: await machineId(),
  deviceName: os.hostname(),
  productId: 'p_123456',
});

storeToken(token); // persist for offline use

On each app launch, use validateAndRefreshToken from the SDK. When the device is online, it refreshes the token from the server. When offline, it verifies the stored token locally using the public key.

import { validateAndRefreshToken } from '@keyforge/client/token';

const { isValid, token, data } = await validateAndRefreshToken({
  token: getStoredToken(),
  publicKeyJwk: '...',
  deviceIdentifier: await machineId(),
  productId: 'p_123456',
});

if (isValid) {
  storeToken(token); // update the stored token when refreshed
  console.log('License token is valid!', data.license.key);
}

For a full guide, check out the docs.


Conclusion

You now have a full licensing setup to protect your commercial Electron app. Keyforge helps protect your application while providing a smooth experience for users, whether they're online or offline.

For a more detailed look, visit the Keyforge documentation.

Simplify your licensing process

Focus on building your product and let us handle licensing. Manage license keys via payments and offer your customers a smooth self-serve experience.