Interactive example

A fast React chessboard built for real games.

Play against random legal moves, queue premoves while the opponent thinks, draw arrows with right-drag, and test the board API directly.

Your moveYou play White
0 moves
Black captured:
8
7
6
5
4
3
2
1a
b
c
d
e
f
g
h
White captured:
Drag or click to move. Right-drag to draw an arrow.

Documentation

Learn the API by using it.

SwiftChess is a controlled React board powered by chess.js. Your application owns the game instance and FEN. The examples below are real boards, so you can test each prop while reading the matching code.

Installation

Install SwiftChess with chess.js. React 19 and React DOM 19 are peer dependencies, so add them explicitly in non-Next React apps.

Terminal
npm install swiftchess chess.js react@19 react-dom@19
Next.js: import swiftchess/style.css once in app/layout.tsx. Any component using the board must be a Client Component.

Quick start

Create one stable Chess instance, store its current FEN in state, and feed every position change back into the board.

Minimal controlled board

Move a piece. The board updates the FEN through onPositionChange while your component owns the state.

Live
chesspositiononPositionChangefillContainer
8
7
6
5
4
3
2
1a
b
c
d
e
f
g
h
White to move

The state contract

01chess

The mutable chess.js game used to validate and apply moves.

02position

The FEN rendered by React. It should match chess.fen().

03onPositionChange

The callback that keeps your React state synchronized.

Do not create new Chess() on every render. Keep the instance stable with useState oruseRef.

Premoves and arrows

Premoves and user annotations work with internal state by default. UseoverlayArrows for engine or explorer hints that right-drag drawing should never mutate.

Guided premoves: Evans Gambit

Play the White moves. Black replies automatically, and during the delay you can queue the next highlighted move as a premove.

Live
premovesonPremovesChangeoverlayArrowsarrows
8
7
6
5
4
3
2
1a
b
c
d
e
f
g
h

Step 1 of 5

Play 1. e4 to begin the Evans Gambit line.

Premove lifecycle

Use onPremoveAdd,onPremoveExecute, andonPremoveReject for UI or network updates.canQueuePremove can enforce your own rules.

Arrow interaction

Users draw and remove annotation arrows with right-drag. UseoverlayArrows for read-only host hints andonArrowCommit for add, remove, and clear events.

Analysis, themes, and sizing

Analysis mode supports ply-keyed move-classification badges. Presets provide a starting palette and boardTheme can override either square color.

Analysis presentation

Ply-keyed move badges, theme presets, overlay arrows, orientation, and responsive sizing can be combined.

Live
modemoveBadgesoverlayArrowsboardThemePresetflipped
8
7
6
5
Brilliant
4
3
2
1a
b
c
d
e
f
g
h
Sizing optionUse it when
fillContainerThe board should responsively match its parent width.
boardSizeYour application controls the exact pixel size.
squareSizeEach square must have a fixed pixel size.
resizableThe user should resize the board with a drag handle.

Prop reference

The practical public API, grouped by responsibility. Onlychess andposition are required.

State and moves7 props
PropTypePurpose
chessChessRequired chess.js instance. SwiftChess validates and applies moves to it.
positionstringRequired current FEN. Update it from onPositionChange.
onPositionChange(fen, move?) => voidRuns after a move, premove, reset, or FEN change.
onMove(move) => voidRuns after a legal move with the chess.js Move object.
initialFenstringPosition restored by resetToInitialFen().
mode'play' | 'analysis'Selects the board workflow. Default: play.
playerColor'w' | 'b'Controls the player side and when premoves may be queued.
Premoves and arrows16 props
PropTypePurpose
premovesPremoveState[]Controlled premove queue. Omit it to use internal state.
onPremovesChange(premoves) => voidReceives the updated controlled premove queue.
onPremoveAdd(premove) => voidRuns when a premove enters the queue.
onPremoveExecute(premove, move) => voidRuns when a queued premove is played.
onPremoveReject(premove) => voidRuns when a queued premove is no longer legal.
canQueuePremove(args) => booleanAdds application-specific premove validation.
relaxedPremoveModebooleanAllows natural premove targets before the opponent move resolves. Default: true.
overlayArrowsArrow[]Read-only host hints such as engine lines or explorer suggestions.
arrowsArrow[]Controlled user-drawn right-drag annotation arrows. Omit it to use internal state.
defaultArrowsArrow[]Initial uncontrolled user annotation arrows.
onArrowsChange(arrows) => voidReceives the updated user annotation arrow list.
onArrowCommit(event) => voidReceives add, remove, and clear lifecycle events for user arrows.
onLiveArrowChange(arrow | null) => voidObserves the transient right-drag preview.
arrowStyleArrowStyleOptionsSets default committed user-arrow color, opacity, and width.
overlayArrowStyleArrowStyleOptionsSets fallback style for overlay arrows.
liveArrowStyleArrowStyleOptionsSets fallback style for the live preview arrow.
Layout and appearance16 props
PropTypePurpose
boardThemePresetBoardThemePresetbrownBoard, chessComClassic, iceBlue, or custom.
boardThemePartial<BoardThemeColors>Overrides the preset light and/or dark square color.
flippedbooleanControls board orientation.
onFlippedChange(flipped) => voidRuns when orientation changes inside the board.
moveBadgesMoveBadgeByPly[]Shows host-provided move classifications keyed by visible ply.
lastMoveBadgeMoveBadge | nullSimple latest-move badge override.
boardSizenumberControlled board width and height in pixels.
squareSizenumberFixes each square size; the board becomes squareSize x 8.
fillContainerbooleanMeasures the parent and fills its available width.
resizablebooleanDisplays the built-in resize handle.
minSize / maxSizenumberMinimum and maximum square size while resizing.
onBoardSizeChange(boardSize, squareSize) => voidRuns when the rendered board size changes.
showLegalMovesbooleanShows legal destination markers. Default: true.
showStatusBarbooleanShows turn, check, and game-over status.
showCapturedPiecesbooleanShows material captured by each side.
classNamestringClass name for the board root wrapper.
Sound3 props
PropTypePurpose
enableSoundsbooleanEnables built-in move, capture, castle, check, and end sounds.
successSoundSrcstringURL for an optional application success sound.
playSuccessSoundbooleanPlays the success sound on a false-to-true change.

Ref API

Use a ChessBoardHandle ref for commands that are not naturally expressed as props.

Imperative controls
const boardRef = useRef<ChessBoardHandle>(null)

<ChessBoard
  ref={boardRef}
  chess={chess}
  position={position}
  onPositionChange={setPosition}
/>

boardRef.current?.flipBoard()
boardRef.current?.goToPreviousMove()
boardRef.current?.setPositionFromFen(fen)
boardRef.current?.resetToInitialFen()
flipBoard()

Toggle orientation.

setFlipped(value)

Set orientation directly.

isFlipped()

Read the current orientation.

goToPreviousMove()

Move backward in local board history.

goToNextMove()

Move forward in local board history.

canGoToPreviousMove()

Check whether backward navigation is available.

canGoToNextMove()

Check whether forward navigation is available.

setPositionFromFen(fen)

Validate and load a FEN. Returns true on success.

resetToInitialFen()

Restore initialFen. Returns true on success.

Exports and values

Import the component, types, and theme map fromswiftchess.

Runtime exports

ChessBoard, BOARD_THEME_PRESETS

Type exports

ChessBoardProps, ChessBoardHandle, ChessBoardMode, BoardThemePreset, BoardThemeColors, MoveBadge, MoveBadgeKind, PremoveState, PremoveValidationArgs, MoveBadgeByPly, Arrow, ArrowCommitEvent, LiveArrow, ArrowStyleOptions

Badge kinds: blunder, mistake, inaccuracy, miss, good, excellent, best, brilliant, book, and onlyMove.