Football intelligence for every competition, every player, every matchday. Built for the World Cup. Built for everything after.
Swale is an open-source football intelligence dashboard. It started with the 2026 FIFA World Cup — 48 teams, 104 matches, three countries — and grew into a platform that covers every major competition year-round.
Live scores and match timelines. Player form across leagues and tournaments. Historical World Cup data going back to 1930. AI-powered previews, summaries, and trend analysis. All in one place, built to be fast, clean, and genuinely useful.
- Live dashboard — real-time scores, lineups, match events, and standings across major competitions
- Player intelligence — form trends, advanced stats (xG, xA, pressures), cross-league comparisons
- World Cup hub — dedicated view for all 48 teams, group tables, bracket, historical tournament data back to 1930
- AI insights — GPT-4o powered match previews, player summaries, and trend narratives
- News feed — aggregated football news filtered by competition, team, or player
- Historical data — every World Cup from 1930 to 2026, all top European leagues by season
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router, RSC, ISR) |
| Language | TypeScript |
| Styling | Tailwind CSS + shadcn/ui |
| Charts | Recharts + D3 |
| Database | Supabase (PostgreSQL) |
| Cache | Upstash Redis |
| AI | OpenAI GPT-4o mini |
| Deployment | Vercel |
| CI/CD | GitHub Actions |
| Code review | CodeRabbit |
| Source | What it provides |
|---|---|
| API-Football | Live scores, lineups, fixtures, current season player & team stats |
| football-data.org | Top league results, standings, historical seasons — free forever |
| openfootball/worldcup.json | All World Cup match data 1930–2026, public domain, no key required |
| FBref | Advanced player metrics — xG, xA, progressive carries, pressures |
- Node.js 20+
- A Supabase account (free tier)
- An Upstash Redis database (free tier)
- An API-Football key (free tier)
- An OpenAI API key
git clone https://github.com/YOUR_USERNAME/swale.git
cd swale
npm installCopy the example env file and fill in your keys:
cp .env.example .env.local# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Upstash Redis
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
# API-Football
API_FOOTBALL_KEY=
# football-data.org
FOOTBALL_DATA_API_KEY=
# OpenAI
OPENAI_API_KEY=npm run devOpen http://localhost:3000.
Run the one-time historical data seed to populate World Cup history and top league data:
npm run db:seedswale/
├── app/ # Next.js App Router
│ ├── (dashboard)/ # Main dashboard layout
│ ├── api/ # API routes (proxies + AI endpoints)
│ └── world-cup/ # World Cup hub pages
├── components/ # Shared UI components
│ ├── ui/ # shadcn/ui base components
│ ├── charts/ # Recharts + D3 visualizations
│ ├── match/ # Match card, timeline, lineups
│ └── player/ # Player cards, trend charts
├── lib/ # Utilities and API clients
│ ├── supabase/ # Supabase client + generated types
│ ├── api-football/ # API-Football wrapper
│ ├── football-data/ # football-data.org wrapper
│ ├── openai/ # OpenAI client + prompt templates
│ └── redis/ # Upstash Redis cache helpers
├── supabase/
│ └── migrations/ # SQL migration files
├── scripts/ # Data sync and seed scripts
│ ├── seed-world-cup.ts # Seeds historical WC data from openfootball
│ └── sync-leagues.ts # Nightly league data sync
├── .github/
│ ├── workflows/ # GitHub Actions CI, preview, cron sync
│ └── PULL_REQUEST_TEMPLATE.md
└── public/ # Static assets
Please read CONTRIBUTING.md before opening an issue.
Apache 2.0 — see LICENSE for details.