All posts

How to set up license keys in an Electrobun application

Nicholas Affonso

February 19, 2026

How to set up license keys in an Electrobun application

Electrobun lets you build fast, lightweight desktop apps with TypeScript and the Bun runtime. In this guide, you'll integrate Keyforge into an Electrobun application to manage license keys.

You'll also see how to connect a payment provider 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

License validation should run from your Bun process, where you have access to native APIs and the file system. When a user enters their license key, send it to Keyforge to activate it on their device.

import { hostname } 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 getDeviceId(),
      deviceName: hostname(),
      productId: 'p_123456',
    }),
  }
);

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

Device identifier

Since Electrobun uses Bun instead of Node.js, there is no node-machine-id package. A clean alternative is to generate a UUID on first launch and persist it with Bun.write:

import { join } from 'path';
import { homedir } from 'os';

async function getDeviceId(): Promise<string> {
  const path = join(homedir(), '.config', 'my-app', 'device-id');
  const file = Bun.file(path);
  if (await file.exists()) return file.text();
  const id = crypto.randomUUID();
  await Bun.write(path, id);
  return id;
}

After activation, store the license key using Bun.write so it can be retrieved on future launches.

Validating a license

On each app launch, validate the stored license key to ensure it's still active. This can also run periodically during the app's lifetime.

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 getDeviceId(),
      productId: 'p_123456',
    }),
  }
);

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

If the license is invalid, prompt the user to re-enter their 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 your 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. Note that isValid remains true in this case, so check the status field to differentiate.

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
}

Offline licensing

If your app needs to run without an internet connection, Keyforge supports offline license tokens. 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 persist it with Bun.write.

import { activateLicense } from '@keyforge/client';
import { hostname } from 'os';

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

await Bun.write('./license-token', token); // persist for offline use

On each app launch, load the stored token and use validateAndRefreshToken from the SDK. When 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 token = await Bun.file('./license-token').text();

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

if (isValid) {
  await Bun.write('./license-token', newToken); // update when refreshed
  console.log('License valid!', data.license.key);
}

For a full guide, check out the docs.


Conclusion

You now have a complete licensing setup for your Electrobun app. Keyforge handles license management and payment automation so you can focus on building your product.

For more details, 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.