bbdata
v0.13.1
Published
Baseball data CLI for querying, scouting reports, and analytics — built for humans and AI agents
Maintainers
Readme
bbdata
Baseball data CLI for querying stats, generating scouting reports, and building analytics pipelines — built for humans and AI agents.
Install
# Global (CLI usage)
npm install -g bbdata
# Local (programmatic API)
npm install bbdataRequires Node.js 18+.
Quick Start
# Pitcher's pitch mix, velocity, spin, whiff rates
bbdata query pitcher-arsenal --player "Corbin Burnes" --format table
# Advance scouting report for a starting pitcher
bbdata report advance-sp --player "Gerrit Cole" --audience coach
# Pitch movement chart (SVG)
bbdata viz movement --player "Shohei Ohtani" -o ohtani.svgCommands
bbdata query [template]
Query baseball data using pre-built templates. Returns structured data in your choice of format.
Key options:
| Flag | Description |
|---|---|
| -p, --player <name> | Player name |
| --players <names> | Comma-separated names (matchups/comparisons) |
| -s, --season <year> | Season year (default: current) |
| -f, --format <fmt> | json (default), table, csv, markdown |
| --source <src> | Force data source: savant, fangraphs, mlb-stats-api |
| --no-cache | Bypass cache |
| --stdin | Read pre-fetched JSON from stdin |
| --data <path> | Load data from a local .json or .csv file (Savant CSV schema) |
Run bbdata query --help for the full option list.
22 templates across 5 categories:
Pitcher (8) — pitcher-arsenal, pitcher-velocity-trend, pitcher-handedness-splits, pitcher-raw-pitches, pitcher-recent-form, pitcher-by-count, pitcher-tto, pitcher-season-profile
Hitter (7) — hitter-batted-ball, hitter-vs-pitch-type, hitter-hot-cold-zones, hitter-handedness-splits, hitter-zone-grid, hitter-raw-bip, hitter-season-profile
Matchup (2) — matchup-pitcher-vs-hitter, matchup-situational
Leaderboard (2) — leaderboard-custom, leaderboard-comparison
Trend (3) — trend-rolling-average, trend-year-over-year, pitcher-rolling-trend
bbdata query hitter-batted-ball --player "Aaron Judge" --format table
bbdata query leaderboard-custom --stat ERA --min-ip 100 --top 10 --format csvbbdata report [template]
Generate scouting reports rendered from Handlebars templates. Reports pull data from multiple query templates automatically.
Key options:
| Flag | Description |
|---|---|
| -p, --player <name> | Player name |
| -a, --audience <role> | coach, gm, scout, analyst (default: analyst) |
| -f, --format <fmt> | markdown (default), json |
| --validate | Run validation checklist on the report |
| --no-strict | Emit stub shell instead of exiting on missing data |
13 templates across 5 categories. An asterisk marks a scaffold: it
fetches no data and renders a structured fill-in shell with "to be filled by
evaluator" lines, meant to be completed by you or handed to an AI. The five
without an asterisk pull live data. --validate warns when you run a scaffold,
because the other checks can only see the form.
Pro Scouting — pro-pitcher-eval, pro-hitter-eval, relief-pitcher-quick
Amateur Scouting — college-pitcher-draft, college-hitter-draft, hs-prospect*
Advance — advance-sp, advance-lineup*
Player Development — dev-progress, post-promotion
Executive — trade-target-onepager, draft-board-card, draft-board-card-pitcher
--audience changes the report body, not just the header line: each
data-driven template opens with a "How to Read This" section written for the
role you asked for.
bbdata report pro-pitcher-eval --player "Corbin Burnes"
bbdata report trade-target-onepager --player "Vladimir Guerrero Jr." --audience gmbbdata viz [type]
Generate data visualizations as SVG.
Chart types:
| Type | Description |
|---|---|
| movement | Pitch movement plot (horizontal break vs vertical break) |
| movement-binned | Count-bubble variant of movement (2.5-in bins) for compact inline use |
| spray | Batted ball spray chart on a schematic field |
| zone | 3x3 strike zone heatmap (xwOBA, with PA per cell) |
| zone-ranked | The same nine zones as ranked bars, for exact comparison in reports |
| rolling | Rolling performance trend, one panel per metric (hitters) |
| pitcher-rolling | 5-start rolling trend for pitchers (velo, Whiff %, K %, CSW %) |
| comparison | Side-by-side hitter season stats for 2+ players — the chart --players drives |
Aliases: pitching-movement, hitting-spray, hitting-zones, hitting-zones-ranked, trend-rolling, player-comparison, compare.
Key options: --theme light|dark|print (print is grayscale with shapes), --colorblind (adds shape as a redundant channel), -a, --audience (coach/analyst/frontoffice/presentation), --size WxH, -o, --output <path>
--players takes a comma-separated list and only applies to chart types that
compare. Passing two or more names to a single-player chart is an error naming
the types that do compare, rather than a silently ignored flag.
bbdata viz spray --player "Aaron Judge" --audience coach
bbdata viz zone --player "Shohei Ohtani" --colorblind
bbdata viz movement --player "Paul Skenes" --theme print --format pdf -o skenes.pdf
bbdata viz comparison --players "Aaron Judge,Shohei Ohtani,Juan Soto" --season 2025Output Formats
All commands support --format:
json(default) — Structured{ data, meta }envelope. Designed for piping to AI agents and scripts.table— Human-readable ASCII table.csv— Standard CSV.markdown— Markdown table.
Decorative output (progress, warnings) goes to stderr. Data goes to stdout. Every format is pipe-safe.
Programmatic API
import { query, report, viz, getConfig, setConfig } from 'bbdata';
const result = await query({
template: 'pitcher-arsenal',
player: 'Corbin Burnes',
season: 2025,
format: 'json',
});
console.log(result.data); // Array of row objects
console.log(result.meta); // { template, source, cached, sampleSize, season, queryTimeMs }All TypeScript types are exported — see QueryOptions, ReportOptions, VizOptions, QueryResult, ReportResult, VizResult, and more.
Data Sources
The CLI tries adapters in preference order and falls back automatically:
- Savant — Pitch-level Statcast data (Baseball Savant CSV)
- FanGraphs — Season-level aggregated stats
- MLB Stats API — Rosters, schedules, and universal fallback for player resolution
Override with --source savant (or fangraphs, mlb-stats-api). Sources can be toggled in config.
Configuration
Config lives at ~/.bbdata/config.json (validated with Zod, graceful defaults if missing or corrupted):
{
"defaultFormat": "json",
"defaultAudience": "analyst",
"cache": {
"enabled": true,
"maxAgeDays": 30
},
"sources": {
"savant": { "enabled": true },
"fangraphs": { "enabled": true },
"mlbStatsApi": { "enabled": true }
}
}Access programmatically with getConfig() / setConfig().
Caching
Query results are cached in SQLite (via sql.js/WASM — zero native dependencies). Cache keys are SHA256 hashes of source:params. Default expiration is 30 days, configurable via cache.maxAgeDays. Bypass with --no-cache.
If sql.js fails to initialize, the CLI continues without cache.
Changelog
See CHANGELOG.md.
