npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hydra-tv/sports

v0.3.7

Published

Sports analytics components (scoreboards, box scores, shot charts, strike zones, spray charts) for basketball and baseball, built on @hydra-tv/ui and @hydra-tv/tokens.

Downloads

1,306

Readme

@hydra-tv/sports

Domain-specific components for basketball and baseball analytics applications — game centers, box scores, shot charts, strike-zone and spray plots, standings. Built on @hydra-tv/ui (reuses DataGrid, ScatterPlot, LineChart, Badge) and @hydra-tv/tokens.

Nothing here is useful outside sports, by design — that's why it's a separate package instead of living in core. If you want the charts without the sport semantics, they're all in @hydra-tv/ui: LineChart, BarChart, ScatterPlot, HeatGrid, Sparkline, Stat, PercentileBar.

Install & setup

{ "dependencies": { "@hydra-tv/sports": "0.3.0", "@hydra-tv/tokens": "0.2.0" } }
import "@hydra-tv/tokens"; // once, at your app's entry point
import { Scoreboard, ShotChart } from "@hydra-tv/sports";

@hydra-tv/ui is a regular dependency (not a peer) since most components here compose core primitives internally — you don't need to install it yourself, but you can import from it directly too.

Component catalog

Sport-agnostic

| Component | What it is | |---|---| | Scoreboard | Head-to-head score, period and clock. Exports formatClock() / ordinalPeriod(). | | TeamChip | Team identity: color bar, abbreviation, record. | | PlayerCard | Number, name, position, team and stat line. | | StatLine | 24 PTS · 8 REB · 6 AST run. Exports slashLine(). | | BoxScore | Player box with league-standard column presets. Exports formatIp(). | | StandingsTable | League table with an optional playoff cut line. | | PlayByPlay | Scrolling game event feed with running score. | | WinProbability | Win probability over time, shaded toward the favorite. |

Basketball

| Component | What it is | |---|---| | CourtDiagram | NBA/NCAA court markings. Exports courtDomain(). | | ShotChart | Makes and misses plotted on the court. | | ShotZoneChart | Zones shaded by FG% against a baseline. Exports courtZone(). | | RotationChart | Player stints across game time over a score-margin strip. |

Baseball

| Component | What it is | |---|---| | FieldDiagram | Field markings. Optional park tricode for MLB walls. Exports fieldDomain() / sprayToXY(). | | SprayChart | Batted balls plotted on the field. | | StrikeZonePlot | Pitch locations against the rule-book zone. | | PitchSequence | At-bat pitch log with location thumbnails. | | CountDisplay | Balls/strikes/outs lamp rows. Exports formatCount(). | | BaseState | Occupied-base diamond with out pips. | | LineScore | Inning-by-inning runs with R/H/E. Exports inningLabel(). |

The one rule that matters: no tally colors

--tally-pgm (red) and --tally-pvw (green) mean program/on-air and preview/next in this design system, and nothing else. Sports UI is full of tempting places to reuse them — green makes and red misses on a shot chart, red/green called strikes, a red LIVE badge, green balls and red strikes on a count board — and every one of those is off limits, because an app that also pulls in @hydra-tv/broadcast would end up with two unrelated meanings competing for the same two colors on one screen. Sports broadcast apps are exactly the apps most likely to do that.

So, throughout this package:

  • Data series use the --ch-1…--ch-4 data-viz tokens, which the token set already marks "never for tally".
  • Status and emphasis use --warn / --info / --ok-text / --err. The LIVE indicator is amber.
  • Where color alone would be ambiguous, shape carries the distinction too: shot-chart makes are circles and misses are crosses; spray-chart hits are filled and outs are hollow.

Don't work around this by passing tally tokens into the color props — they exist for real team colors, which is a different problem (see below).

What this package deliberately doesn't do

  • No league data (except park outlines). No team colors, no logos, no headshots. Those stay props: color, logo, photo. SprayChart / FieldDiagram do ship MLB wall geometry behind a park tricode (BOS, NYY, …), because a spray chart without Fenway's wall isn't Fenway — fence is still there for everything else, and the table will still go stale when a club moves.
  • No stat math. Components render numbers you have already computed. The only arithmetic in the whole package is formatting-level: win percentage in StandingsTable, made/attempted tallies in the chart legends, minutes summed in RotationChart, and the formatIp/slashLine/formatCount helpers. Rate stats, park factors and win-probability models are the app's business.
  • No data fetching. Nothing here knows about an API.

Coordinate systems

The three spatial plots take the coordinates their sport's public data already uses, so a feed can be passed through with at most a unit conversion:

| Plot | Coordinates | |---|---| | ShotChart / CourtDiagram | Feet, origin at the center of the basket. Same axes as NBA LOC_X/LOC_Y, which are tenths of a foot — divide by 10. | | StrikeZonePlot / PitchSequence | Statcast plate_x / plate_z in feet, catcher's view. | | SprayChart / FieldDiagram | Feet from home plate, +x toward right field — or a spray angle and distance via sprayToXY(). |

Each diagram can also be used bare, as a ScatterPlot background layer, via asLayer — see CourtDiagram.md for how that transform works if you're plotting something the built-in charts don't cover.

Content conventions (worth following if you extend this package)

  • Casing: UPPERCASE for stat codes, labels and team abbreviations; mixed case for player names and play descriptions.
  • Numbers are always tabular (--numeric-features) so columns line up, and rates keep their sport's conventional format: .312 not 0.312, 6.2 innings not 6.67, 9-17 for made-attempted.
  • Jargon (PGM is not one of them here — but ATB, BBE, WHIP, xBA, +/-) is intentional; the audience knows it.

See the playground app's SPORTS kitchen sink plus the GAME CENTER and PITCH LAB reference screens (apps/playground) for these components composed into full analytics layouts.