An open API service indexing awesome lists of open source software.

https://github.com/echecsjs/fen

Parse and stringify FEN (Forsyth–Edwards Notation) chess positions. Strict TypeScript, no-throw API.
https://github.com/echecsjs/fen

chess fen parser typescript

Last synced: about 7 hours ago
JSON representation

Parse and stringify FEN (Forsyth–Edwards Notation) chess positions. Strict TypeScript, no-throw API.

Awesome Lists containing this project

README

          

# @echecs/fen

[![Spec](https://img.shields.io/badge/Spec-FIDE-green.svg)](SPEC.md)

Parse and stringify
[FEN](https://www.chessprogramming.org/Forsyth-Edwards_Notation)
(Forsyth-Edwards Notation) chess positions. Strict TypeScript, no-throw API.

## Install

```bash
npm install @echecs/fen
```

## Usage

### Parsing

```typescript
import { parse } from '@echecs/fen';

const position = parse(
'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
);
// => { board, turn, castlingRights, enPassantSquare, halfmoveClock, fullmoveNumber }

parse('invalid');
// => null
```

`parse` never throws. It returns `null` when the input is not a valid FEN
string. The result can be passed directly to the `Position` constructor from
`@echecs/position`:

```typescript
import { Position } from '@echecs/position';

const position = new Position(parse(fen));
```

#### Error and warning callbacks

Errors indicate invalid FEN syntax — the string cannot be parsed. Warnings
indicate a successfully parsed position that is suspicious (e.g. missing king).

```typescript
const position = parse(fen, {
onError(error) {
// FEN is malformed — parse returns null.
console.error(`[${error.offset}] ${error.message}`);
},
onWarning(warning) {
// FEN is valid but the position is suspicious.
console.warn(warning.message);
},
});
```

Errors are reported for:

- Wrong number of fields
- Invalid piece placement (bad piece type, wrong rank length)
- Invalid active color
- Invalid castling availability
- Invalid en passant target square
- Invalid halfmove clock (non-numeric or negative)
- Invalid fullmove number (non-numeric or less than 1)

Warnings are reported for:

- Missing king for either side
- Pawn on rank 1 or 8
- More than 8 pawns per side
- More than 16 pieces per side

### Stringifying

```typescript
import { stringify } from '@echecs/fen';

stringify(position);
// => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
```

`stringify` always succeeds.

### Constants

```typescript
import { STARTING_FEN } from '@echecs/fen';

STARTING_FEN;
// => 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
```

## API

### `parse(input: string, options?: ParseOptions): PositionData | null`

Parses a FEN string into a `PositionData` object. Returns `null` if the input is
not a valid FEN string.

### `stringify(position: PositionData): string`

Serializes a `PositionData` object into a FEN string. Omitted fields use
defaults (empty board, white to move, all castling rights, no en passant,
halfmove clock 0, fullmove number 1).

### `STARTING_FEN`

The FEN string for the standard starting position.

### Types

Chess types (`Color`, `Square`, `Piece`, `CastlingRights`, `PositionData`, etc.)
are re-exported from `@echecs/position`. Parse/stringify types are defined
locally:

```typescript
import type {
CastlingRights,
Color,
EnPassantSquare,
File,
ParseError,
ParseOptions,
ParseWarning,
Piece,
PieceType,
PositionData,
Rank,
SideCastlingRights,
Square,
} from '@echecs/fen';
```

```typescript
interface ParseOptions {
onError?: (error: ParseError) => void;
onWarning?: (warning: ParseWarning) => void;
}

interface ParseError {
column: number; // 1-indexed column in the FEN string
line: number; // Always 1 (FEN is single-line)
message: string;
offset: number; // 0-indexed offset into the FEN string
}

interface ParseWarning {
column: number;
line: number;
message: string;
offset: number;
}
```

See `@echecs/position` for the full type definitions of `PositionData`, `Color`,
`Square`, `Piece`, and other chess types.

## License

MIT