NBA Feed
팀 뉴스와 경기 정보를 제공, 점수는 직접 확인할 때까지 숨겨져 있습니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Unofficial 2026 NFL schedule viewer — kickoff times in your timezone, the week-by-week slate, where to watch, venues, W-L-T standings with division seeding, the single-elimination playoff bracket, live scores, follow-teams, and calendar export. React + Vite.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Live: the-nfl-schedule.netlify.app ·
ismayc.github.io/nfl-schedule
An unofficial viewer for the NFL season: every game in your timezone, week by week, live
scores, standings, the playoff bracket, and league leaders.
No backend, no API keys, no tracking. The whole app is a static bundle plus a committed
snapshot of the season — it renders a complete season with zero requests on load.
Star a team from any game card, standings roREADME 전문 보기 ↗Live: the-nfl-schedule.netlify.app · ismayc.github.io/nfl-schedule
An unofficial viewer for the NFL season: every game in your timezone, week by week, live scores, standings, the playoff bracket, and league leaders.
No backend, no API keys, no tracking. The whole app is a static bundle plus a committed snapshot of the season — it renders a complete season with zero requests on load.
| View | What it does |
|---|---|
| 📋 Schedule | Every game grouped by the calendar day you see, opening on today — previous days are hidden behind a toggle. Filter by team or by the teams you follow. |
| 📆 Week | One NFL week at a glance, as day columns (Thu · Sat · Sun · Mon) rather than a long list — with the Sunday slate split by kickoff window (early, late, Sunday night). Page through weeks 1–18, and see who's on a bye. |
| 📊 Standings | By division (all eight, division winners marked) or by conference (seeded 1–16 with the playoff cutline). W-L-T, win %, points for/against and differential, home/road and division splits, streak. |
| 🔀 Scenarios | Pick a result (a win, a loss, or a tie) for the games that are left. Once 6 or fewer are open, every combination of them is played out under the official tiebreakers, and a grid per conference shows the share of outcomes that lands each team at each seed. Tap a cell to see exactly which results produce it; tap a line to pick them. A picked game has no score, so a seed that hangs on the points tiebreakers is marked, not shown as settled. Once every game is picked, it shows the seeding, how each tie broke, and the Wild Card round. |
| 🏆 Playoffs | The single-elimination bracket — seven seeds per conference, the No. 1 seed's bye, re-seeding every round, the two conferences converging on the Super Bowl. Projected from the standings until the field is set. |
| 📈 Stats | Season totals, league leaders across passing / rushing / receiving / defense, scoring margin, and the playoff race per conference. |
| 📜 History | Every completed season back to 2021, in three modes: one season in full (bracket + both final tables), that season's stats (totals, all eight leaderboards, scoring margin), and every Super Bowl with the seed each finalist came from. |
Star a team from any game card, standings row, or team panel to highlight it across
every view, filter the schedule to "My teams", and scope live alerts to it. Clicking any
team opens a team panel — splits, form, roster, and what's next. Plus: light/dark
themes, spoiler-free mode, shareable URLs, live alerts for notable moments, a game-detail
modal with a quarter line score and season series, .ics calendar export (whole season or
one team's), and installable-PWA support.
Everything comes from ESPN's public, keyless, CORS-open feeds.
The season is committed, not fetched. scripts/fetch-schedule.mjs generates
src/data/schedule.js, src/data/teams.js, and src/data/leaders.js, and mirrors team
logos into public/logos/. The app therefore renders a complete season with zero
requests on load. At runtime, ESPN's scoreboard is polled only to overlay games that are
live or just finished (every 30s while a game is in progress, 2 min otherwise, never once
the season ends).
That snapshot is refreshed by .github/workflows/refresh-data.yml, which regenerates the
data, runs the test suite against it, and opens a PR. Standings are derived from the
committed scores, so a bad refresh surfaces as a failing test rather than a quietly wrong
table.
week.number, so the schedule
is organized by NFL week (1–18), not just by date. Preseason is skipped — its weeks
restart at 1 and would collide with the regular season.level=3 — the default tree only nests
conference → 16 teams.pct = (w + ½t) / gp); miscounting one as a loss would corrupt
every derived seed.With those handled, derived W-L-T, home/road splits, and division records match ESPN's published standings exactly for all 32 teams.
Two format details drive most of the postseason logic:
Like basketball, football is too high-frequency to enumerate every score as an event, so
the model stores a final score plus a quarter line score, and player leaderboards come
from pre-aggregated season stat lines rather than being summed from events. The live badge
shows the quarter (Q3, OT) rather than a running clock a 30-second poll can't keep
honest, and alerts surface moments that change how a game feels — kickoff, a lead change,
a one-score fourth quarter (within 8), and the final — by diffing poll snapshots.
src/data/history.js holds every completed season back to 2021. The floor is where
two format changes line up: the playoffs went to 14 teams in 2020 (seven seeds a
conference, only the 1 seed on a bye, re-seeded every round — the bracket this app
models), and the regular season went to 17 games in 2021. Starting there means every
archived season is directly comparable with the one on screen.
Each season commits its final conference standings, its 13 postseason games, its
season totals, and its leader boards (as {id, rank, value} against a deduped
per-season player table). The ~272 regular-season games are summarised into those totals
rather than committed, which is why five extra seasons cost ~145KB.
Nothing derived is committed. The bracket is rebuilt at runtime by the same
buildBracket() the live season uses — it takes the committed seeds as an optional
second argument, since an archived season has no regular-season games to seed from. The
leader boards were built by the same leaderboard(), and the scoring margin re-derives
through the same rankScoring(). Box scores aren't committed either: the detail modal
fetches them from ESPN by event id, and every archived game has one.
npm run fetch:history # rebuilds the archive (a season in progress is skipped)
A season joins the archive by itself the week its Super Bowl is played: the script runs up to the season the app is on and drops any season with no champion.
One real-world wrinkle the data keeps honest: 2022 was a 271-game season. The Buffalo–Cincinnati game was abandoned after Damar Hamlin's cardiac arrest and never made up, so those two teams played 16 games, not 17. The tests assert that specifically rather than a flat "every team plays 17".
npm install
npm run dev # local dev server
npm test # unit + render tests, against frozen data
npm run test:data # the live suite: the real committed data (what a refresh must pass)
npm run test:coverage # tests with coverage (100% enforced)
npm run build # production bundle
npm run coverage:badge # tests with coverage, writes public/coverage.json
npm run fetch:schedule # regenerate committed data from ESPN
npm run check:schedule # report drift between committed data and the live feed
npm run verify:live # check the live overlay's assumptions against a game in progress
scripts/ uses Node built-ins and relative imports only — no node_modules imports —
so CI can run the data jobs on a bare checkout with no install step. A CI job enforces it.
The suite leans on real data rather than hand-made fixtures, because real data contains the
edge cases you wouldn't think to invent. Coverage is enforced at 100% in CI
(vite.config.js thresholds), so an untested branch fails the build.
Real, but frozen. There are two suites, and they never mix:
The main suite (npm test, the 100% coverage gate) never sees the modules the
refresh rewrites. A plugin in vite.config.js resolves every import of
src/data/schedule.js, leaders.js, and teams.js to a frozen week-2 stand-in under
test/fixtures/frozen/, whoever the importer is. Coverage therefore cannot move when
the data does: the gate passes unchanged with those three modules made to throw on
import.
The live suite (npm run test:data, test/live/) reads the real modules and has no
coverage threshold. It holds invariants (the season's shape, unique ids, known teams,
finite stats, standings that recount W-L-T from the games, division winners seeded
first) and a smoke render of every view, every game dialog, and every team panel,
checked for the residue of a bad value (NaN, Invalid Date, 1969). This is the gate
a refresh has to pass. Only things true on any day of any season belong in it; it
passes on both this week's board and the whole 2025 season, tie and postseason
included.
Standings are derived from a real completed season (test/fixtures/season-2025.js)
and checked to match ESPN's published W-L-T for all 32 teams.
The bracket is tested against the complete 2025 postseason — 13 games — because the 2026 bracket doesn't exist until January. It reproduces the real outcome, champion and all. That fixture caught a seeding/bracket coupling bug a synthetic test would have sailed past.
Empty-season states matter here: the committed 2026 snapshot has no games played yet, so every view is tested in both its populated and empty forms.
One gap the suite structurally cannot close: the live overlay's field mapping was inferred
from completed and scheduled games, and the tests mock ESPN using the same inferences — so
they agree by construction. npm run verify:live, run during a game, is the only check that
compares those assumptions to reality.
Built with base: './', so the same dist/ works at a domain root (Netlify) and under a
subpath (GitHub Pages /nfl-schedule/) with no separate build.
ci.yml on every push to main, gated on
tests passing.netlify.toml on each
push), with deploy previews on pull requests.Created by Chester Ismay. Source on GitHub.
Unofficial fan project. Not affiliated with, endorsed by, or sponsored by the NFL. Team names and logos are trademarks of their respective owners. Schedule, results, and player data via ESPN's public feeds.
MIT licensed.