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

chess-openings-graph

v0.1.0

Published

Chess openings database exposed in a form of a graph.

Readme

chess-openings-graph: Library containing openings theory

The library fully embeds Lichess opening tables and allows users to fetch information about chess openings and their particular variations.

Key features:

  • Basic openings data: you can get openings by ECO code, name, PGN, FEN, EPD, etc.
  • Hierarchy: each opening has parent and children getters that allow you to move up and down in the opening hierarchy
  • Simplicity: all the openings and relations between them are embedded directly into the library bundle, therefore the library does not have any dependencies and is synchronous and fast

Important:

  • The library as of now contains only ~4k named openings. It does not contain all possible lines of those openings. It contains only named variations
  • Since it embeds all the openings, the bundle size is rather large; if you're using it on the frontend, consider lazy import

Quick start

  1. Install the library using your preferred package manager:
npm install chess-openings-graph
  1. Use it in your code:
import { graph } from 'chess-openings-graph'

const rootOpenings = graph.rootOpenings.map((opening) => opening.name)
console.log(rootOpenings)

Documentation

A few words about terminology:

  • PGN: Portable Game Notation. Each opening has a unique PGN, and fetching an opening by PGN is O(1). PGN contains the whole history of a chess game
  • ECO: list of codes used to classify openings. Multiple openings can share the same ECO code (e.g. A00 is assigned to many rare and unusual openings)
  • FEN: Forsyth–Edwards Notation. FEN contains only the state of the board but not the full game history; therefore, a single FEN can theoretically correspond to multiple PGNs
  • EPD: Extended Position Description. Based on FEN notation. In this library implementation, it just removes the last 2 FEN fields with move counts
  • Root opening: opening that is not a variation of any other opening
  • Terminal variation: opening that does not have any variations

The library was built with encapsulation and immutability in mind, so it relies heavily on ECMAScript getters.

The library exports two JS objects: rawGraph and graph:

  • rawGraph is a plain JS object that contains the embedded openings data. It acts as a "Database"
  • graph is an instance of a private class that defines useful getters and methods to fetch data from the rawGraph. It acts in a certain sense as a "Data Access Object"

You should mostly use graph for your own purposes.

graph satisfies the following interface:

export interface Graph {
  openings: readonly GraphNode[] // getter that returns all the openings
  rootOpenings: GraphNode[] // getter that returns openings that are not variations of another opening
  terminalVariations: GraphNode[] // getter that returns openings that don't have any further variations
  getOpeningByPgn: (pgn: string) => GraphNode | undefined
  getOpeningsByName: (name: string) => GraphNode[]
  getOpeningsByEco: (eco: string) => GraphNode[]
  getOpeningsByFen: (fen: string) => GraphNode[]
  getOpeningsByEpd: (epd: string) => GraphNode[]
}

As you may notice, those getters and methods return objects that satisfy the GraphNode interface (expanded for the convenience of readers):

export type GraphNode = {
  eco: string
  name: string
  pgn: string
  fen: string
  epd: string
  parent: GraphNode | undefined
  children: GraphNode[]
  isRootOpening: boolean
  isTerminalVariation: boolean
  predecessors: GraphNode[]
}

All of those properties are actually getters as well.

For those who want to fork / contribute

The project uses the following development setup:

  • Node v22+ (although it's probably possible to use an older version)
  • npm as package manager
  • tsdown as bundler
  • Oxfmt for formatting
  • Oxlint for linting
  • Vitest for writing specifications (tests)
  • Husky for pre-commit hooks
  • ...and a bunch of other libraries needed for graph generation.

The conventional commits guideline should be followed, but it is currently checked neither by CI nor by pre-commit hooks.

Important folders:

  • openings/: contains openings taken from Lichess
  • scripts/: code related to graph generation
  • specs/: contains specifications (unit tests)
  • src/: code that later gets bundled into the library distribution

License

This project is licensed under the MIT License - see the LICENSE file for details.


Special thanks to Lichess for providing opening tables