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

hltb-client

v1.0.0

Published

A TypeScript client for the HowLongToBeat API. Get game completion times programmatically.

Downloads

116

Readme

hltb-client

A TypeScript client for the HowLongToBeat API. Get game completion times programmatically.

Installation

npm install hltb-client

Usage

Basic Example

import { HLTBClient } from 'hltb-client';

const client = new HLTBClient();

// Search for games
const games = await client.search('Elden Ring');
console.log(games[0]);
// {
//   id: '68151',
//   name: 'Elden Ring',
//   imageUrl: 'https://howlongtobeat.com/games/68151_Elden_Ring.jpg',
//   completionTimes: { main: 60, mainExtra: 101, completionist: 136, allStyles: 98 },
//   platforms: 'PC, PlayStation 4, PlayStation 5, Xbox One, Xbox Series X/S',
//   releaseYear: 2022,
//   reviewScore: 92
// }

// Get a single game
const game = await client.searchOne('The Witcher 3');

// Get just completion times
const times = await client.getCompletionTimes('Zelda Breath of the Wild');
console.log(times);
// { main: 50, mainExtra: 98, completionist: 189, allStyles: 97 }

CommonJS

const { HLTBClient } = require('hltb-client');

const client = new HLTBClient();
const games = await client.search('Dark Souls');

API Reference

new HLTBClient(options?)

Creates a new HLTB client instance.

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | userAgent | string | Chrome UA | Custom user agent string | | tokenCacheDuration | number | 3600000 | Token cache duration in ms (1 hour) |

client.search(query, options?)

Search for games by name.

Parameters:

  • query (string) - Search query
  • options (object, optional)
    • limit (number) - Max results to return (default: 20)
    • platform (string) - Filter by platform
    • sortBy (string) - Sort by: 'popular', 'name', 'rating', 'length', 'release'

Returns: Promise<HLTBGame[]>

const games = await client.search('Mario', { limit: 5, sortBy: 'popular' });

client.searchOne(name)

Search for a single game by name. Returns the best match.

Parameters:

  • name (string) - Game name to search for

Returns: Promise<HLTBGame | null>

const game = await client.searchOne('Hollow Knight');
if (game) {
  console.log(`${game.name}: ${game.completionTimes.main} hours`);
}

client.getCompletionTimes(name)

Get completion times for a game. Convenience method that returns just the times.

Parameters:

  • name (string) - Game name to search for

Returns: Promise<HLTBCompletionTimes>

const times = await client.getCompletionTimes('Celeste');
console.log(`Main story: ${times.main} hours`);
console.log(`Completionist: ${times.completionist} hours`);

Types

HLTBGame

interface HLTBGame {
  id: string;                           // HowLongToBeat game ID
  name: string;                         // Game name
  imageUrl?: string;                    // Cover image URL
  completionTimes: HLTBCompletionTimes; // Completion times in hours
  platforms?: string;                   // Available platforms
  releaseYear?: number;                 // Release year
  reviewScore?: number;                 // User score (0-100)
}

HLTBCompletionTimes

interface HLTBCompletionTimes {
  main?: number;         // Main story (hours)
  mainExtra?: number;    // Main + extras (hours)
  completionist?: number; // 100% completion (hours)
  allStyles?: number;    // Average of all playstyles (hours)
}

HLTBSearchOptions

interface HLTBSearchOptions {
  limit?: number;    // Results to return (default: 20)
  platform?: string; // Platform filter
  sortBy?: 'popular' | 'name' | 'rating' | 'length' | 'release';
}

Error Handling

The client throws errors for network issues or authentication failures:

try {
  const games = await client.search('Some Game');
} catch (error) {
  if (error.message.includes('authentication')) {
    console.error('Failed to authenticate with HLTB');
  } else {
    console.error('Network error:', error.message);
  }
}

How It Works

This client interfaces with HowLongToBeat's internal API:

  1. Fetches an authentication token from /api/search/init
  2. Uses the token to make search requests to /api/search
  3. Caches tokens for 1 hour to minimize requests

Rate Limiting

HowLongToBeat doesn't publish rate limits. This client:

  • Caches auth tokens to reduce requests
  • Makes one token request per hour max
  • Does not implement request throttling (add your own if needed)

Disclaimer

This is an unofficial client. HowLongToBeat doesn't provide a public API, so this library may break if they change their internal API. Use responsibly.

License

MIT