npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

license-key-infrastructure

v1.1.1

Published

Reusable RSA-signed license verification for Electron and Node.js apps

Downloads

106

Readme

License Key Infrastructure

Reusable RSA-signed license verification for Electron and Node.js apps. Decouple licensing from your app and use the same infrastructure across multiple projects.

Features

  • RSA-SHA256 signature verification
  • HWID binding — tie license to a specific machine, or use hwid: "*" for any machine
  • Expiry dates — checked against online time (worldtimeapi.org, timeapi.io) to prevent clock-back bypass
  • Electron integration — license gate window, IPC handlers, preload script
  • CLI tools — generate keys, sign licenses, get machine ID
  • TypeScript — full type definitions included

Installation

Choose one of these methods:

# From npm (recommended after publishing)
npm install license-key-infrastructure

# From GitHub
npm install Wisernage/PathofLicense

# Local / monorepo
npm install file:../PathofLicense

For Electron apps, Electron is a peer dependency (optional — only needed for the /electron module).

Monorepo / Workspaces

If using npm or pnpm workspaces, add to your root package.json:

{
  "workspaces": ["PathofLicense", "your-app"]
}

Then in your app:

{
  "dependencies": {
    "license-key-infrastructure": "workspace:*"
  }
}

Integration Checklist (Electron)

  1. Installnpm install license-key-infrastructure
  2. Add public key — Place license-public.pem in your app (e.g. next to main.js)
  3. Create gate — Call createLicenseGate or integrate with { app, publicKeyPath, appName }
  4. Register IPC — Call registerIpcHandlers() (or use integrate() which does this automatically)
  5. Verify on startup — In app.whenReady(): verify license, show gate if invalid, quit if user closes
  6. Expose getMachineId (optional) — Add license:getMachineId to your main window preload so users can copy their machine ID

Quick Start (Electron)

Option A: One-call integrate()

// main.js
const { app } = require('electron');
const path = require('path');
const { integrate } = require('license-key-infrastructure/electron');

const licenseGate = integrate({
  app,
  publicKeyPath: path.join(__dirname, 'license-public.pem'),
  appName: 'My App',
  iconPath: path.join(__dirname, 'icon.ico'),
});

app.whenReady().then(async () => {
  if (app.isPackaged) {
    let result = await licenseGate.verifyLicense();
    while (!result.valid) {
      const applied = await licenseGate.showLicenseGate(result);
      if (!applied) return app.quit();
      result = await licenseGate.verifyLicense();
    }
  }
  // ... create main window, etc.
});

Option B: Manual setup with createLicenseGate

// main.js
const { app } = require('electron');
const path = require('path');
const { createLicenseGate } = require('license-key-infrastructure/electron');

const licenseGate = createLicenseGate({
  app,
  publicKeyPath: path.join(__dirname, 'license-public.pem'),
  appName: 'My App',
  iconPath: path.join(__dirname, 'icon.ico'),
});

licenseGate.registerIpcHandlers();

app.whenReady().then(async () => {
  if (app.isPackaged) {
    let result = await licenseGate.verifyLicense();
    while (!result.valid) {
      const applied = await licenseGate.showLicenseGate(result);
      if (!applied) return app.quit();
      result = await licenseGate.verifyLicense();
    }
  }
  // ... create main window, etc.
});

Preload for main window (optional)

To expose getMachineId to the renderer (e.g. for a "Copy Machine ID" button):

getMachineId: () => ipcRenderer.invoke('license:getMachineId'),

The license gate window uses its own preload from the package. No extra setup needed.


Gate UI Customization

Customize the license gate window with optional parameters:

createLicenseGate({
  app,
  publicKeyPath,
  appName: 'My App',
  gateTitle: 'Activate Your License',           // Override the h2 title
  gateStyles: 'h2 { color: #00ff00; }',        // Extra CSS
  gateHtml: '<html>...</html>',                // Full HTML replacement (see below)
});
  • gateTitle — Override the default ${appName} — License Required title
  • gateStyles — Extra CSS appended to the default styles
  • gateHtml — Full HTML replacement. Your HTML must use window.licenseGate.apply(json) and window.licenseGate.done(applied). Use {{ERROR_MSG}} and {{TITLE}} as placeholders for dynamic content.

Core API (Node.js, no Electron)

const license = require('license-key-infrastructure');

// Verify license data (object)
const result = await license.verifyLicenseData(licenseData, {
  publicKeyPath: '/path/to/license-public.pem',
});

// Verify license file
const result = await license.verifyLicenseFile('/path/to/license.json', {
  publicKeyPath: '/path/to/license-public.pem',
});

// Verify and save pasted JSON
const result = await license.saveAndVerifyLicense(
  '/path/to/save/license.json',
  jsonString,
  { publicKeyPath: '/path/to/license-public.pem' }
);

// Get machine ID
const machineId = license.getMachineId();

CLI Tools

Generate keypair (run once)

npx license-generate-keys
# Or with custom paths:
npx license-generate-keys --keys-dir ./my-keys --public-out ./app/license-public.pem

Sign a license

# License for any machine, expires in 1 month
npx license-sign "*"

# License for specific machine
npx license-sign 79cb54a01f16e0e01c5995a26ec65b7d17561dbd86a68f28c981892877fc93e5

# Custom expiry
npx license-sign "*" 2025-12-31

# No expiry
npx license-sign "*" --no-expiry

# Custom paths
npx license-sign "*" --keys-dir ./my-keys --out ./license.json

Get machine ID

npx license-get-machine-id

License File Format

{
  "payload": {
    "hwid": "*",
    "expiry": "2025-12-31"
  },
  "signature": "base64..."
}
  • hwid: Machine ID or "*" for any machine
  • expiry: Optional. ISO date (YYYY-MM-DD). Requires internet at startup to verify time.

Integration with Installer (NSIS)

For optional license paste during install, write to %APPDATA%\Your App Name\license.json in your custom NSIS page. The app will validate on launch.


Using in Multiple Projects

  1. Generate keys once (or per product) — keep the private key secret.
  2. Bundle license-public.pem with each app.
  3. Use createLicenseGate or integrate with your app name and paths.
  4. Share the same keypair across apps if you want one license to work for multiple products, or use separate keypairs per product.

Publishing to npm

When ready to publish:

npm login
npm publish

Consumers can then use npm install license-key-infrastructure.