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

@eg-utils/client

v0.2.1

Published

Authenticated Epic Games HTTP client and device authorization CLI for Bun.

Readme

@eg-utils/client

npm CI License: MIT

Authenticated Epic Games HTTP requests, refresh-token persistence, and device authorization for Bun.

Installation

bun add @eg-utils/client

Requires Bun 1.3 or later. Tokens are stored in the operating system's credential store through Bun.secrets.

Bun.secrets uses Keychain Services on macOS, a Secret Service provider such as GNOME Keyring or KWallet on Linux, and Credential Manager on Windows. Bun currently describes this API as experimental, so applications should pin and test their supported Bun versions.

Authorize an account

The package installs an eg-authorize command:

bunx @eg-utils/client --id <client-id> --secret <client-secret>

For a client tied to an Epic deployment:

bunx @eg-utils/client \
  --deployment-id <deployment-id> \
  --id <client-id> \
  --secret <client-secret>

For a legacy Epic service that requires the eg1 access-token format:

bunx @eg-utils/client \
  --id <client-id> \
  --secret <client-secret> \
  --type eg1

The command prints a one-time sign-in URL. After sign-in, it stores the token under the authenticated Epic account ID and OAuth client ID. It does not print the token or secret.

Authorization is also available as an API:

import { authorize } from '@eg-utils/client';

const { accountId } = await authorize({
  id: process.env.EPIC_CLIENT_ID!,
  secret: process.env.EPIC_CLIENT_SECRET!,
  tokenType: 'eg1',
  onVerification: (url) => console.log(`Sign in: ${url}`),
});

console.log(`Authorized ${accountId}`);

Use Client directly

Create a client with the same OAuth application and the account ID printed by the authorization command:

import Client from '@eg-utils/client';

const accountId = '<epic-account-id>';

const launcherApp2Client = new Client({
  accountId,
  id: process.env.EPIC_CLIENT_ID!,
  secret: process.env.EPIC_CLIENT_SECRET!,
  tokenType: 'eg1',
});

const response = await launcherApp2Client.fetch(
  `https://account-public-service-prod.ol.epicgames.com/account/api/public/account/${accountId}`,
);

if (!response.ok) {
  throw new Error(`Epic request failed: ${response.status} ${await response.text()}`);
}

const account = await response.json();
console.log(account);

client.fetch follows the standard Fetch API and adds a current bearer token unless the request already has an Authorization header. Requests that provide their own authorization do not read the stored Epic token. Access tokens are refreshed shortly before expiration and saved automatically. Concurrent loads, refreshes, saves, and deletes are deduplicated per client instance.

If an OAuth application requires a deployment or the legacy Epic Games eg1 token form, pass deploymentId or tokenType: 'eg1' to both authorize and the Client constructor. Access tokens are refreshed 30 seconds before expiration by default; pass tokenRefreshBuffer in milliseconds to change that window, or set it to 0 to disable early refresh.

Extend Client

Extend Client when an application needs fixed OAuth credentials, typed events, or service-specific request methods. The subclass can call this.fetch(...) for requests that need the stored Epic token:

import Client from '@eg-utils/client';

export namespace AccountsClient {
  export type EventMap = {
    request: [url: string];
  };
}

export class AccountsClient extends Client<AccountsClient.EventMap> {
  public constructor(accountId: string) {
    super({
      accountId,
      id: process.env.EPIC_CLIENT_ID!,
      secret: process.env.EPIC_CLIENT_SECRET!,
    });
  }

  public async getAccount(): Promise<unknown> {
    const url = `https://api.epicgames.dev/epic/id/v1/accounts?accountId=${this.accountId}`;
    this.emit('request', url);

    const response = await this.fetch(url);

    if (!response.ok) {
      throw new Error(`Epic request failed: ${response.status} ${await response.text()}`);
    }

    return response.json();
  }
}

const client = new AccountsClient('<epic-account-id>');
console.log(await client.getAccount());

Token storage

The OAuth client ID is used as the credential-store service and the Epic account ID is used as the credential name. Large tokens are split into integrity-checked chunks to fit credential-store limits. A replacement token is committed only after all of its chunks have been written.

To remove a stored token:

await client.delete();

Exports

The default and named Client exports are equivalent. authorize, runAuthorizeCLI, and their public types are exported from the package root and from @eg-utils/client/authorize.

Development

bun install
bun run check

License

MIT

This project is not affiliated with or endorsed by Epic Games, Inc.