A Rust library and CLI for converting between SCID (.si4/.sn4/.sg4) and PGN formats. Fast, accurate, and functional on Windows, Mac, and Linux.
Caution
This library is still in beta; you must build it from source. For now! Once some additional testing has been done, you'll be able to download it separately.
# build it
cargo build --release
# dump a SCID database to PGN
scidtopgn /path/to/database
# save it to a file
scidtopgn /path/to/database -o output.pgn
# go the other direction — PGN into a fresh SCID database
scidtopgn import games.pgn -o mydbNote
Specify database paths without extensions — use mydb, not mydb.si4.
scidtopgn /path/to/database # stdout
scidtopgn /path/to/database -o out.pgn # to file
scidtopgn /path/to/database --count # just tell me how many games
scidtopgn export /path/to/database # explicit subcommand, same thing| Argument | Short | Required | Default | Description |
|---|---|---|---|---|
database | - | Yes | - | Path to SCID database (without file extension) |
--output | -o | No | stdout | Output file path |
--count | - | No | - | Just print the number of games and exit |
--overwrite | - | No | - | Overwrite the output file if it already exists |
--verbose | -v | No | - | Verbose output |
scidtopgn import games.pgn -o mydb # create or append
scidtopgn import games.pgn -o mydb --overwrite # start fresh
scidtopgn import - -o mydb # read from stdin
scidtopgn import games.pgn -o mydb --on-error=abort # strict modeBy default, import appends to an existing database. Bad games get skipped with a warning unless you pass --on-error=abort.
| Argument | Short | Required | Default | Description |
|---|---|---|---|---|
pgn_file | - | Yes | - | PGN file to import (use - for stdin) |
--output | -o | Yes | - | Output database path (without file extension) |
--overwrite | - | No | - | Overwrite existing database instead of appending |
--on-error | - | No | skip | Error handling strategy: skip or abort |
--verbose | -v | No | - | Verbose output |
use scidtopgn::Database;letmut db = Database::open("path/to/database")?;for game in db.games(){let game = game?;println!("{}", game.to_pgn());}// or grab a specific gamelet game = db.get_game(0)?;println!("{} vs {}", game.white, game.black);cargo build # debug
cargo build --release # optimized
cargo test --workspace # run the full suite
cargo run -p scidtopgn-cli -- /path/to/database # run without installingIf you're the kind of person who wants to understand the binary format, see SCID_DATABASE_FORMAT.md.
Licensed under the MIT License.

