A fast, typed CS2 demo parser for Node.js, Bun, and modern browsers. Both exports use an embedded WASM Snappy decoder; production installs require no native addons.
Parses .dem files and live HTTP GOTV broadcasts from Counter-Strike 2, providing typed access to entities, players, game events, and more.
npm install cs2parserimport { createReadStream } from 'fs';
import { DemoReader, EntityMode } from 'cs2parser';
const parser = new DemoReader();
parser.gameEvents.on('player_death', event => {
const attacker = event.attackerPlayer;
const victim = event.player;
if (attacker && victim) {
console.log(`${attacker.name} killed ${victim.name} with ${event.weapon}`);
}
});
parser.on('end', () => {
for (const player of parser.playerControllers) {
console.log(player.name, player.kills, player.deaths, player.position);
}
});
await parser.parseDemo(createReadStream('path/to/demo.dem'), { entities: EntityMode.ALL });EntityMode.ALL enables player helpers and full entity state. Use EntityMode.ONLY_GAME_RULES for round events and game rules, or the default EntityMode.NONE when you only need messages and basic player info. Each DemoReader handles one demo or broadcast.
See Parsing demos for supported inputs, completion results, settings, and cancellation.
Import from cs2parser/browser to parse a file or web stream without Node globals or separate WASM assets:
import { DemoReader, EntityMode } from 'cs2parser/browser';
// file is a File from an <input type="file"> or drag-and-drop.
const parser = new DemoReader();
parser.gameEvents.on('player_death', event => console.log(event.weapon));
await parser.parseDemo(file.stream(), { entities: EntityMode.ALL });See Browser usage for fetch, metadata, runtime requirements, and WASM Snappy details.
await new DemoReader().parseHttpBroadcast('https://relay.example.com/match-id/', {
entities: EntityMode.ALL
});Uses the same events as demo parsing. See Live HTTP broadcasts for relay options, mid-stream joins, and cancellation.
| Guide | Topics |
|---|---|
| Parsing demos | Inputs, entity modes, settings, reader state, and cancellation |
| Pausing and seeking | Tick-boundary playback controls, FullPackets, and seekable sources |
| Reading metadata | Header, server info, and file info without a full parse |
| Browser usage | Files, web streams, metadata, and WASM Snappy |
| Live HTTP broadcasts | GOTV relays, options, descriptors, and wire format |
| Players and pawns | Rosters, lookups, bot analysis, and helper properties |
| Entities and match state | Teams, game rules, and typed entity access |
| Smokes | Seed voxels, density simulation, and visual comparison |
| Game and parser events | Typed game events and parser lifecycle events |
| Network messages | Subscriptions, user commands, and message discovery |
| Encrypted demo chat | Match keys, public chat decryption, and browser support |
| Development | Entity types, protobuf bindings, and generated registries |
| Performance | Benchmark commands, methodology, and custom cases |
| Examples | Runnable scripts and command-line usage |
Upgrading from 1.x? See the migration guide.
Creating this library wouldn't be possible without awesome work of:
- LaihoE, creator of demoparser
- Saul, creator of demofile-net
- markus-wa, creator of demoinfocs-golang
Huge thanks to all of them, as they all have helped me in some way or the other during the past few years.