JavaScript Move Generator with Strictly Legal Move Generation (x88 & Bitboards)

Discussion of chess software programming and technical issues.

Moderator: Ras

mario carbonell
Posts: 22
Joined: Tue Dec 12, 2017 7:14 pm

JavaScript Move Generator with Strictly Legal Move Generation (x88 & Bitboards)

Post by mario carbonell »

Hi everyone,

After some years away from chess programming, I've published a JavaScript move
generator that I've been working on. It's now available on GitHub and NPM.

GitHub: https://github.com/mcarbonell/chess-movegen-js
NPM: npm install chess-movegen-js
Live Demo: https://mcarbonell.github.io/chess-movegen-js/

Key Features:

• Strictly legal move generation (no pseudo-moves requiring make/unmake validation)
• Integrated pin detection during generation
• Check, checkmate, and stalemate detection as part of move generation
• Tactical move enrichment (safe squares, hanging pieces, winning captures, discovered checks)
• Two implementations: 0x88 and Bitboards with magic tables
• UCI engine with Web Worker support

Performance (Node.js v20, x88 implementation):
- Depth 4: 197,281 nodes in 83ms (2.4M NPS)
- Depth 5: 4,865,609 nodes in 871ms (5.6M NPS)
- Depth 6: 119,060,324 nodes in ~17s (7.0M NPS)

All standard Perft positions pass correctly.

Technical Approach:

The main difference from typical move generators is that pins are detected
upfront and moves are filtered during generation, not after. This means:

1. Calculate all checking squares before generating moves
2. Detect pinned pieces and pin directions
3. Generate only moves that respect pin constraints
4. For king moves, only generate to pre-calculated safe squares
5. When in check, only generate moves to valid escape squares

This eliminates the need for make/unmake validation cycles entirely.

Interesting Finding:

In JavaScript, the 0x88 implementation significantly outperforms bitboards
(~40% faster). I suspect this is due to:
- JavaScript's 53-bit integer limitation requiring BigInt for 64-bit operations
- BigInt operations being slower than regular integer arithmetic
- Better cache locality with the simpler 0x88 array structure

Both implementations are included in the repo for educational comparison.

The project includes:
- Complete source code (MIT license)
- Interactive web demo with drag & drop board
- Comprehensive Perft test suite
- UCI engine implementation
- CI/CD with GitHub Actions

I'd appreciate any feedback, especially on:
- Performance optimization opportunities
- Edge cases I might have missed
- Comparison with other JavaScript chess libraries

The code is well-commented and might be useful for anyone learning chess
programming or needing a move generator for web-based chess projects.

Cheers,
Mario
op12no2
Posts: 554
Joined: Tue Feb 04, 2014 12:25 pm
Location: Gower, Wales
Full name: Colin Jenkins

Re: JavaScript Move Generator with Strictly Legal Move Generation (x88 & Bitboards)

Post by op12no2 »

Very nice Mario. It's a shame that BitInts are still so slow; but they are getting quicker over time. The other option is using 2 x Uint32Array elements, but I found that is still slower than mailbox; and ugly. You'll be pleased to know PERFT 6 from startpos achieved 12M nps on my 7950x (using the web demo UI). Good luck with your developments...
Aleks Peshkov
Posts: 967
Joined: Sun Nov 19, 2006 9:16 pm
Location: Russia
Full name: Aleks Peshkov

Re: JavaScript Move Generator with Strictly Legal Move Generation (x88 & Bitboards)

Post by Aleks Peshkov »

Nice to see non-bitboard development. All bitboard engines look very similar in their basics.
mario carbonell
Posts: 22
Joined: Tue Dec 12, 2017 7:14 pm

Re: JavaScript Move Generator with Strictly Legal Move Generation (x88 & Bitboards)

Post by mario carbonell »

Thanks op12no2 and Aleks!

@op12no2: 12M NPS on your 7950x is fantastic! That's nearly 2x what I'm seeing on my machine. The BigInt limitation is indeed the main bottleneck for bitboards in JS - that's why I'm publishing the x88 implementation for the NPM package.

@Aleks: Thanks for sharing Petrel! I agree that x88 offers more room for
creative approaches.

I'm now trying to implement a wasm version of the bitboards with Rust, and try to measure the improvement.

Cheers,
Mario