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

@qpjoy/electron-launcher

v2.3.0

Published

Product-facing Electron Launcher client for MX Launcher release, update, rollout, AppCenter, and network integration.

Downloads

857

Readme

@qpjoy/electron-launcher

Product-facing npm entry for MX Launcher.

Applications install this package directly and point it at an MX Launcher backend. The package hides the internal split between core, embed, and standalone adapters.

For production SDK delivery, MX Launcher also supports role-specific packages:

| Package | Use when | | --- | --- | | @qpjoy/mx-launcher-core | sharing protocol, manifest, capability, release, and ABI contracts | | @qpjoy/mx-launcher-standalone | building a capability owner such as MX-H2I or Luopan | | @qpjoy/mx-launcher-embed-sdk | building an embed app such as AppCenter, H2O, or an AppCenter-managed app | | @qpjoy/electron-launcher | using the unified Electron facade or existing compatibility exports |

Both delivery styles are supported. The role-specific split is preferred for external teams because it keeps owner-only APIs out of embed apps. The unified Electron package remains useful for monorepo demos, legacy products, and apps that want a single import surface. Packages with the same major version must be protocol-compatible; breaking protocol or broker ABI changes require a new major version.

See the package design notes in ../README.md, ../launcher-core/README.md, ../launcher-standalone/README.md, and ../launcher-embed-sdk/README.md.

import { createElectronLauncher, defineLauncherProduct } from '@qpjoy/electron-launcher';

export const product = defineLauncherProduct({
  productId: 'h2o',
  displayName: 'H2O',
  mode: 'embed',
  standaloneChannelProductId: 'mx-h2i',
  launcherActions: {
    network: true,
    release: true,
    update: true,
    rollout: true,
    appCenter: true
  }
});

const launcher = createElectronLauncher({
  baseUrl: 'http://127.0.0.1:18090',
  productId: product.productId,
  mode: product.mode,
  standaloneChannelProductId: product.standaloneChannelProductId,
  requiredCapabilities: ['user.session', 'network.proxy', 'network.status']
});

const connection = launcher.mode === 'embed'
  ? await launcher.connect()
  : null;

if (connection && !connection.ok) {
  console.warn(connection.state, connection.message);
}

standalone mode is for the full Launcher shell. embed mode is for product apps hosted by a standalone broker session. Embed apps do not allocate their own WireGuard peer lease or apply DNS/route state; call launcher.connect() and request scoped capabilities from the selected standalone channel.

Runtime adapters

The package exposes optional runtime adapters as separate subpaths so products can depend only on the capabilities they own:

| Subpath | Purpose | | --- | --- | | @qpjoy/electron-launcher | launcher client, product definition, standalone/embed SDK facade | | @qpjoy/electron-launcher/wireguard | WireGuard profile rendering, route proof, and peer recovery | | @qpjoy/electron-launcher/system-domain-proxy | standalone local PAC/proxy edge plus OS PAC apply/restore/verify | | @qpjoy/electron-launcher/standalone-data-plane | read-only standalone lease/data-plane route diagnostics |

For standalone products, keep the state model split into two phases:

  1. connectNetwork() proves the control plane accepted the app and issued a lease.
  2. WireGuard/PAC/DNS apply and route proof prove the local data plane is ready.

Products should not display connected only because a lease exists. Use the read-only data-plane diagnostic before claiming traffic is ready:

import {
  applyElectronLauncherStandaloneDataPlane,
  diagnoseElectronLauncherStandaloneDataPlane
} from '@qpjoy/electron-launcher/standalone-data-plane';

const dataPlane = diagnoseElectronLauncherStandaloneDataPlane({
  routePlan: session.routePlan,
  leaseIp: session.lease.leaseIp,
  serviceVip: session.lease.serviceVip
});

if (!dataPlane.ok) {
  console.warn(dataPlane.state, dataPlane.message);
}

const applied = await applyElectronLauncherStandaloneDataPlane({
  userDataDir: app.getPath('userData'),
  profileName: `${product.productId}.conf`,
  routePlan: session.routePlan,
  privateKey: session.wireGuard.privateKey,
  dnsDomains: ['mxinfo-inc.cn'],
  ownerId: `${product.productId}:${installId}`,
  productId: product.productId,
  instanceId: installId,
  dnsHosts: ['luopan.mxinfo-inc.cn'],
  dnsZones: ['mxinfo-inc.cn'],
  failOnOwnershipConflicts: true
});

Inside the electron-dock/mx-launcher monorepo, demos depend on this package with workspace:*, so local package changes are used by MX-H2I, Luopan, and future launcher demos during development. Release builds should consume a published semver version from npm, matching the V1 HDO local-vs-published workflow.

System PAC is intended for Launcher standalone owners. For MX-H2I the local edge listens on 127.0.0.1:2053 by default and serves both /proxy.pac and an HTTP/CONNECT proxy on TCP, plus a UDP DNS relay on the same port. Internal domains are resolved with the Internal IP from the route plan, 10.88.88.88 by default, through the WireGuard AllowedIPs path. The Domestic gateway 10.88.0.1 is only a fallback relay/cache target; all other domains fall back to the previous system proxy when one is detected or provided. If another standalone launcher already owns the same local edge port, a later instance reuses it.

On macOS, local PAC alone only covers proxy-aware traffic such as browsers. When systemResolver: 'dynamic' is enabled, the package installs a runtime SystemConfiguration supplemental DNS entry for matched domains and points it at 127.0.0.1:<pacPort>, so ping, CLI tools, and non-PAC applications resolve the same Internal names without writing /etc/hosts or /etc/resolver. A file resolver mode remains available as an explicit fallback and only manages files with the MX_ELECTRON_LAUNCHER_RESOLVER marker.

import { createElectronLauncherSystemDomainProxy } from '@qpjoy/electron-launcher/system-domain-proxy';

const systemDomainProxy = createElectronLauncherSystemDomainProxy({
  userDataDir: app.getPath('userData'),
  pacPort: 2053
});

await systemDomainProxy.apply({
  enabled: true,
  domains: ['internal.mx', 'svc.cluster.local'],
  matchMode: 'proxy',
  proxy: '127.0.0.1:2053',
  pacPort: 2053,
  systemResolver: 'dynamic',
  dnsServers: ['10.88.88.88', '10.88.0.1'],
  fallbackProxy: '127.0.0.1:7890'
});

// Later, when the launcher channel disconnects:
await systemDomainProxy.disable('disconnect');