Skip to main content

Sunfish logo

Sunfish is a simple, but strong chess engine, written in Python. With its simple UCI interface, and removing comments and whitespace, it takes up just 126 lines of code!

There is also a (somewhat) stronger NNUE based sunfish, which you can also play against on Lichess. It's only 4096 bytes for the whole engine, so the neuron network is very small.

Because Sunfish is small and strives to be simple, the code provides a great platform for experimenting. People have used it for testing parallel search algorithms, experimenting with evaluation functions, and developing deep learning chess programs. Fork it today and see what you can do!

The name Sunfish refers to the Pygmy Sunfish, which is among the very few fish to start with the letters 'Py'. The use of a fish is in the spirit of great engines such as Stockfish, Zappa and Rybka. In terms of Heritage, Sunfish borrows much more from Micro-Max by Geert Muller and PyChess.

Play against sunfish!

The easiest way to play against sunfish is @sunfish-engine on Lichess, where you can also play against the stronger @sunfish-nnue-engine (see more below.)

The second easiest way is to play in your terminal:

$ pip install sunfish
$ sunfish

Playing sunfish in the terminal

Or, from a repo checkout, just run sunfish_ui/fancy.py -cmd ./sunfish.py.

Using sunfish with GUIs and tournament tools

The engine speaks UCI: point any tool at sunfish-uci (after pip install sunfish) or ./sunfish.py (from a checkout).

  • UCI GUIs (Arena, Cute Chess, PyChess, BanksiaGUI): add an engine, protocol UCI, command sunfish-uci.

  • WinBoard / XBoard: use the PolyGlot adapter with the shipped config tools/polyglot.ini (tested with PolyGlot 2.0.4; CI drives a real adapter session).

  • Command-line matches with fastchess or cutechess-cli:

    fastchess -engine cmd=sunfish-uci name=sunfish \
              -engine cmd=<other> name=other \
              -each proto=uci tc=30+1 -rounds 10 -games 2
    

    (see docs/TESTING.md for the full methodology).

Troubleshooting

./sunfish.py automatically runs with pypy3 if installed (recommended, much stronger), otherwise python3. If the engine fails to start, run sunfish_ui/fancy.py with -debug to see the underlying error, and make sure python3 is on your PATH. On Windows, .py engines are launched through your current Python interpreter automatically.

Packing

Sunfish can also be packed into a single self-extracting executable of about 3kb:

$ tools/build/pack.sh sunfish.py packed.sh
Total length: 3310
$ ./packed.sh
go wtime 1000 btime 1000 winc 1000 binc 1000
info depth 1 score cp 0 pv d2d4
bestmove d2d4

The packed version uses a simplified UCI protocol by the TCEC 4k rules.

NNUE version

nnue_4k/ is a sunfish whose evaluation is classic's exact piece-square score plus a trained neural residual — with the whole accumulator and evaluation head packed into one Python integer, so a wide net costs a handful of big-int operations per node. It is measured about +200 Elo over classic at tournament time controls, the engine still packs to a few kilobytes, and every quantized net is certified (lane-exactness, incremental == from-scratch, exact antisymmetry) before it plays a game. See nnue_4k/README.md for the architecture, the training pipeline, and the measured results.

Features

  1. Built around the simple, but efficient MTD-bi search algorithm, also known as C*.
  2. Filled with classic "chess engine tricks" for simpler and faster code.
  3. Efficiently updatable evaluation function through Piece Square Tables.
  4. Uses standard Python collections and data structures for clarity and efficiency.

Testing

Sunfish uses pytest for testing. To run the tests:

python3.12 -m pytest

You can also run specific test files:

python3.12 -m pytest tests/test_mate_puzzles.py

Or even specific tests:

python3.12 -m pytest tests/test_mate_puzzles.py::test_mate_in_one

Make sure you have installed the required dependencies (defined in pyproject.toml):

uv sync  # or: pip install chess tqdm pytest pytest-asyncio

Limitations

Sunfish supports all chess rules, except the 50-move draw rule.

There are many ways in which you may try to make Sunfish stronger. First you could change from a board representation to a mutable array and add a fast way to enumerate pieces. Then you could implement dedicated capture generation, check detection and check evasions. You could also move everything to bitboards, implement parts of the code in C or experiment with parallel search!

The other way to make Sunfish stronger is to give it more knowledge of chess. The current evaluation function only uses piece square tables - it doesn't even distinguish between midgame and endgame. You can also experiment with more pruning - currently only null move is done - and extensions - currently none are used. Finally Sunfish might benefit from a more advanced move ordering, MVV/LVA and SEE perhaps?

An easy way to get a strong Sunfish is to run it with the PyPy Just-In-Time interpreter — the launcher at the top of sunfish.py picks pypy3 automatically when installed. Measured on the current engine (fixed-depth battery, identical node counts): PyPy 3.11 searches ~2.7x faster than CPython 3.14 (81 vs 30 knps), worth on the order of 100 Elo at fast time controls.

(Historical footnote: sunfish once ran fastest under PyPy 2.7, and an old version of this table said so. Modern sunfish requires Python >= 3.8 — the code uses the walrus operator — and modern PyPy 3 has long since closed the gap.)

Family

The sunfish family keeps growing. Here is a (very incomplete) list of interesting derivatives:

  • μSunfish - A heavily reworked MicroPython Sunfish derivative for ESP32-class microcontrollers, with bounded memory, stronger search, configurable skill levels, and UCI support.
  • Numbfish - A compact Sunfish-based Python engine that adds an incrementally updated NumPy NNUE evaluation.
  • sunfish_rs - A Rust port of Sunfish that preserves much of its search architecture while using more native Rust representations. (Lichess bot).
  • Carnatus - A small Go port of Sunfish intended to keep the engine minimal but readable.
  • Sunfish.js - A JavaScript port of Sunfish designed to run under Node.js or directly in a browser via a web worker.
  • Chess.Mojo - A Sunfish-based UCI chess engine used as a proof of concept for the Mojo programming language.
  • sunfish.lua - A direct human translation of the classic Sunfish implementation from Python into Lua.
  • Solefish - A C++ port that deliberately follows the original Sunfish program structure closely as a learning exercise.
  • sunfishNNUE - A Sunfish derivative that replaces its classical evaluation with NNUE evaluation using Stockfish-style neural networks.
  • Moonfish - A Sunfish-derived engine adapted from Western chess to Chinese chess/Xiangqi with UCCI support.
  • ParallelChessAI - A Sunfish-derived experiment investigating parallelization of chess-engine search.
  • numworks_usunfish - A μSunfish adaptation designed to run as a playable chess engine on NumWorks calculators.
  • chess-badger2040 - A standalone offline chess game that embeds a MicroPython Sunfish port on the RP2040-based Badger 2040 e-ink device.
  • micropython-sunfish - An early port of Sunfish to MicroPython for running the engine on constrained embedded hardware.
  • peterhinch/micropython-sunfish - Another independent MicroPython adaptation that makes Sunfish usable as an embedded chess-engine component.
  • Vector-Anki-Sunfish - A project integrating Sunfish with the Anki Vector robot to let the robot participate in chess.
  • chess-genetic-algorithm-sunfish - An experimental Sunfish derivative using genetic algorithms to evolve or tune chess-engine parameters.
  • sunfishDDA - A Sunfish experiment exploring dynamic difficulty adjustment rather than simply maximizing engine strength.
  • Blindfold-Sunfish - A Sunfish modification aimed at blindfold chess and alternative ways of interacting with the engine.
  • Moonfish - A tiny C chess engine originally inspired by Sunfish that subsequently developed its own substantially different implementation and search approach.

License

GNU GPL v3

Metadata

Release files for sunfish 2026.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sunfish 2026.1
File Size Uploaded
sunfish-2026.1.tar.gz 187.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sunfish 2026.1
File Interpreter ABI Platform
sunfish-2026.1-py3-none-any.whl Python 3 none any Details

Total release size: 254.1 kB

Release files / sunfish-2026.1.tar.gz

Download URL sunfish-2026.1.tar.gz
Size 187.8 kB
Tags Source
SHA-256 checksum
How to use checksums
73f0114d6ff636b736e34416c1b269d8697e4420af884cfb1475fd3252bbff43
BLAKE2b-256 checksum
How to use checksums
7da5a4f4e7f68cbec762d965a066eff8f8299ab0598757a6350668f89251c50a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release files / sunfish-2026.1-py3-none-any.whl

Download URL sunfish-2026.1-py3-none-any.whl
Size 66.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2623bacbe265c78183765aa1c67e847bd912134a25cc3f56396fee54d08948a0
BLAKE2b-256 checksum
How to use checksums
f27940545c0cbea260172156bb3baf5aafd3af0b8c2fc7387a324545ad7e5721
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2026.1 This release

2 release files

2026

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page