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

@react-chess-tools/react-chess-bot

v1.0.1

Published

Logical CPU players for react-chess-game powered by UCI engines in Web Workers.

Downloads

24

Readme

npm version npm downloads License: MIT TypeScript

Table of Contents

Overview

@react-chess-tools/react-chess-bot adds CPU players to ChessGame.Root without introducing a second game provider or any required UI.

Each ChessBot.Player:

  • watches the current position through useChessGameContext()
  • runs a worker-backed UCI search
  • chooses a move
  • applies it through methods.makeMove()

The package is logic-only by design. It does not render controls, panels, or bot cards for you.

Features

  • Composable - Mount one or two bots inside an existing ChessGame.Root
  • Level Presets - Lichess-style levels 1-8 via BOT_LEVELS
  • Advanced Tuning - Override the preset with custom engine settings
  • Move Variability - Use MultiPV to avoid fully deterministic play
  • Move Delay - Add fixed or randomized delay before the move is applied
  • Lifecycle Callbacks - Observe readiness, thinking, selected moves, played moves, and errors
  • Engine Flexibility - Works with both stockfish and fairy-stockfish
  • History Safe - Automatically stops in non-live positions and discards stale analysis

Installation

npm install @react-chess-tools/react-chess-game @react-chess-tools/react-chess-bot

If you want analysis widgets as well, install @react-chess-tools/react-chess-stockfish separately.

Engine Setup

This package does not bundle an engine worker. You must provide a Stockfish-compatible worker path through workerOptions.workerPath.

Common setups:

  • Use classic Stockfish for levels 4-8
  • Use Fairy-Stockfish for levels 1-3
  • Use Fairy-Stockfish for every level if you want one worker family across all presets

Minimal worker configuration:

workerOptions={{
  workerPath: "/stockfish.js",
  engineType: "stockfish",
}}

Low levels 1-3 rely on negative skillLevel presets, so engineType: "stockfish" will throw an explicit runtime error for those levels. Use engineType: "fairy-stockfish" instead.

For worker setup details, see the @react-chess-tools/react-chess-stockfish README.

Quick Start

import { ChessBot } from "@react-chess-tools/react-chess-bot";
import { ChessGame } from "@react-chess-tools/react-chess-game";

function App() {
  return (
    <ChessGame.Root fen="r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3">
      <ChessGame.Board />
      <ChessGame.KeyboardControls />
      <ChessBot.Player
        color="b"
        strength={{ level: 6 }}
        variability="medium"
        moveDelay={{ min: 250, max: 600 }}
        workerOptions={{ workerPath: "/stockfish.js" }}
      />
    </ChessGame.Root>
  );
}

API Reference

ChessBot.Player

ChessBot.Player is a logic-only component that returns null.

It must be rendered inside ChessGame.Root.

Props

| Name | Type | Default | Description | | ---------------- | ---------------------- | -------------- | -------------------------------------------------- | | color | "w" \| "b" | - | Side controlled by the bot | | workerOptions | WorkerOptions | - | Worker path and engine selection | | strength | BotStrength | { level: 4 } | Preset level or custom engine parameters | | variability | BotVariability | "none" | Candidate-move selection strategy | | moveDelay | BotTiming | 0 | Delay before the chosen move is applied | | paused | boolean | false | Stops the bot without unmounting it | | autoPlay | boolean | true | Lets the bot think and apply moves automatically | | onStateChange | (state) => void | - | Called whenever bot state changes | | onThinkStart | (fen, color) => void | - | Called when analysis begins | | onMoveSelected | (move) => void | - | Called when a move is chosen, before delay elapses | | onMove | (move) => void | - | Called after the move is successfully applied | | onError | (error) => void | - | Called when the bot enters the error state |

BotStateSnapshot

onStateChange receives:

type BotStateSnapshot = {
  color: "w" | "b";
  status:
    | "initializing"
    | "idle"
    | "thinking"
    | "delaying"
    | "paused"
    | "error";
  isThinking: boolean;
  isReady: boolean;
  currentFen: string;
  lastMove: BotMove | null;
  error: Error | null;
};

Bot Levels

The package exports BOT_LEVELS with the resolved preset data.

| Level | Approx. Elo | Skill | Move Time | Max Depth | Recommended Engine | | ----- | ----------- | ----- | --------- | --------- | ------------------ | | 1 | 800 | -9 | 50ms | 5 | fairy-stockfish | | 2 | 1100 | -5 | 100ms | 5 | fairy-stockfish | | 3 | 1400 | -1 | 150ms | 5 | fairy-stockfish | | 4 | 1700 | 3 | 200ms | 5 | stockfish | | 5 | 2000 | 7 | 300ms | 5 | stockfish | | 6 | 2300 | 11 | 400ms | 8 | stockfish | | 7 | 2700 | 16 | 500ms | 13 | stockfish | | 8 | 3000 | 20 | 1000ms | 22 | stockfish |

BotStrength

Use a preset level:

<ChessBot.Player color="b" strength={{ level: 5 }} workerOptions={...} />

Or override the engine parameters directly:

<ChessBot.Player
  color="b"
  strength={{
    custom: {
      skillLevel: 8,
      limitStrength: true,
      elo: 1900,
      moveTimeMs: 350,
      depth: 10,
    },
  }}
  workerOptions={{ workerPath: "/stockfish.js" }}
/>

Notes:

  • moveTimeMs takes precedence when both moveTimeMs and depth are provided
  • if custom strength omits both moveTimeMs and depth, the package falls back to the default bot move time

BotVariability

Presets:

  • "none": strongest move only
  • "low": MultiPV 2, small threshold
  • "medium": MultiPV 3, weighted selection
  • "high": MultiPV 5, wider threshold and more randomness

Custom configuration:

variability={{
  multiPV: 4,
  thresholdCp: 35,
  selection: "weighted",
  temperature: 25,
}}

BotTiming

Use a fixed delay:

moveDelay={400}

Or a randomized delay range:

moveDelay={{ min: 200, max: 700 }}

Examples

Human vs bot:

<ChessGame.Root fen="r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 3 3">
  <ChessGame.Board />
  <ChessBot.Player
    color="b"
    strength={{ level: 6 }}
    variability="medium"
    workerOptions={{ workerPath: "/stockfish.js" }}
  />
</ChessGame.Root>

Bot vs bot:

<ChessGame.Root>
  <ChessGame.Board />
  <ChessBot.Player
    color="w"
    strength={{ level: 4 }}
    moveDelay={150}
    workerOptions={{ workerPath: "/stockfish.js" }}
  />
  <ChessBot.Player
    color="b"
    strength={{ level: 4 }}
    moveDelay={150}
    workerOptions={{ workerPath: "/stockfish.js" }}
  />
</ChessGame.Root>

Low-level bot with Fairy-Stockfish:

<ChessGame.Root fen="rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2">
  <ChessGame.Board />
  <ChessBot.Player
    color="b"
    strength={{ level: 2 }}
    variability="high"
    workerOptions={{
      workerPath: "/fairy-stockfish/worker.js",
      engineType: "fairy-stockfish",
    }}
  />
</ChessGame.Root>

Storybook

Interactive examples are available in the project Storybook:

  • human vs bot
  • Fairy-Stockfish low-level presets
  • bot vs bot autoplay

Live demo: react-chess-tools.vercel.app

License

This project is MIT licensed.