An automated data pipeline that scrapes, processes, and visualizes global tech industry layoff data.
ไธไธช่ชๅจๅๆฐๆฎ็ฎก้๏ผ็ฌๅใๅค็ๅนถๅฏ่งๅๅ จ็็งๆ่กไธ่ฃๅๆฐๆฎใ
Quick Start ยท Features ยท Architecture ยท Data Sources
๐ก Supports EN / ไธญๆ language toggle โ switch instantly without page reload.
| Feature | Description |
|---|---|
| ๐ท๏ธ Web Scraper | Multi-strategy scraper with live Airtable shared-view extraction, CSV mirror fallback, and offline sample data |
| ๐งน Data Processing | Pandas-based pipeline that cleans, normalizes, and aggregates raw data into analysis-ready JSON |
| ๐ Interactive Dashboard | Glassmorphism-styled ECharts dashboard with animated gradients, responsive layout, dynamic date-range subtitles, and homepage-first analysis modules |
| ๐งญ SEO Trend Report | Static trend-report.html page with indexable analysis text, chart-backed findings, methodology notes, FAQ, and structured data |
| ๐๏ธ Reports Archive | /reports/ archive entry designed for daily, weekly, monthly, and quarterly layoff trend reports |
| ๐ค GEO / AI-Readable Summary | llms.txt and ai-summary.json expose canonical facts, data range, methodology, and source files for AI answer engines |
| ๐งญ SEO Discovery Files | Generated sitemap.xml and robots.txt expose the dashboard, reports, and AI-readable files to crawlers |
| ๐ One-Command Pipeline | python main.py runs the complete scrape โ process โ visualize workflow |
| ๐ณ Docker Ready | Multi-stage Dockerfile + Compose โ docker compose up for instant deployment |
| ๐ Offline-Capable | Built-in curated dataset ensures the project works even without network access |
# Clone & start โ one command!
git clone https://github.com/frankwang0909/tech-layoff-tracker.git
cd tech-layoff-trackerOpen http://localhost:8080/ in your browser. Done! ๐
# Clone the repository
git clone https://github.com/frankwang0909/tech-layoff-tracker.git
cd tech-layoff-tracker
# Create virtual environment
python -m venv venv
source venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r requirements.txt
# Run the full pipeline
python main.py
# Serve the dashboard locally
Open http://localhost:8080/ or directly open index.html.
python main.py # Full pipeline: Scrape โ Process โ Chart
python main.py --skip-scrape # Skip scraping, use existing data
python main.py --verbose # Debug output
python server.py --port 3000 # Serve on custom portThis project uses GitHub Actions to deploy the generated static site to GitHub Pages:
| Setting | Value |
|---|---|
| ๐ Trigger | Push to main and manual dispatch |
| ๐ฆ Artifact | Entire repository root (including index.html and visualization/) |
| ๐ Deploy | GitHub Pages with optional custom domain |
| ๐งญ Entry Point | Root index.html serves the dashboard homepage directly |
- Push this repo to GitHub
- Go to Settings โ Pages โ Source and select GitHub Actions
- Push a commit to
mainor run Actions โ Deploy Static Redirects โ Run workflow - Your dashboard will be live at:
If you configure a custom domain, the root path should render the dashboard directly.
https://frankwang0909.github.io/tech-layoff-tracker/
tech-layoff-tracker/
โ
โโโ index.html # ๐ Generated homepage dashboard
โโโ trend-report.html # ๐งญ Generated SEO trend report
โโโ llms.txt # ๐ค LLM guidance and canonical facts
โโโ ai-summary.json # ๐ค Machine-readable answer summary
โโโ sitemap.xml # ๐งญ Generated sitemap index
โโโ sitemap-main.xml # ๐งญ Generated main-page sitemap
โโโ sitemap-reports.xml # ๐งญ Generated reports sitemap
โโโ sitemap-topics.xml # ๐งญ Generated industry/country sitemap
โโโ robots.txt # ๐งญ Generated crawler directives
โโโ layoff_chart.html # โช Root-level legacy redirect
โโโ main.py # ๐ One-command entry point
โโโ requirements.txt # Python dependencies
โโโ .gitignore
โ
โโโ scraper/ # ๐ท๏ธ Data Collection
โ โโโ __init__.py
โ โโโ config.py # Scraper configuration
โ โโโ layoffs_fyi_scraper.py # Multi-strategy web scraper
โ
โโโ analysis/ # ๐ง Data Processing
โ โโโ __init__.py
โ โโโ data_processor.py # Clean, aggregate, export JSON
โ
โโโ visualization/ # ๐ Chart Generation
โ โโโ generate_charts.py # Jinja2 template โ HTML dashboard
โ โโโ layoff_chart.html # Legacy redirect kept for old links
โ
โโโ data/
โ โโโ raw/ # Raw scraped CSV
โ โโโ processed/ # Aggregated JSON files
โ โโโ industry_pages.json # ๐งฉ Topic data for industry pages
โ โโโ country_pages.json # ๐งฉ Topic data for country pages
โ
โโโ industries/ # ๐งฉ Generated industry topic pages
โโโ countries/ # ๐งฉ Generated country/region topic pages
โ
โโโ reports/
โโโ index.html # ๐ Generated reports archive
โโโ daily/ # ๐ Generated significant daily report pages (noindex)
โโโ weekly/ # ๐ Generated recent weekly report pages
โโโ monthly/ # ๐ Generated monthly report pages
โโโ quarterly/ # ๐ Generated quarterly report pages
โโโ yearly/ # ๐ Generated yearly report pages
โโโ layoff_report_2025_2026.md # Detailed analysis report (ไธญๆ)
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ SCRAPE โโโโโโถโ PROCESS โโโโโโถโ VISUALIZE โ
โ โ โ โ โ โ
โ layoffs.fyi โ โ pandas โ โ Jinja2 + โ
โ Airtable API โ โ aggregation โ โ ECharts โ
โ + fallbacks โ โ โ JSON โ โ โ HTML โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
The scraper uses a 3-tier strategy for maximum reliability:
| Priority | Strategy | Description |
|---|---|---|
| 1๏ธโฃ | Live Airtable Shared View | Discover the current Airtable iframe from layoffs.fyi, then read the shared-view payload exposed to public visitors |
| 2๏ธโฃ | GitHub CSV Mirror | Fallback snapshot from a community-maintained CSV mirror |
| 3๏ธโฃ | Offline Dataset | Curated sample data from verified public reports (always works) |
Ethical scraping practices:
- Polite request delays (
REQUEST_DELAY = 1.0s) - Proper
User-Agentheader - Configurable retry with backoff
- Only targets publicly available data
- Preserves current embed rotations by discovering the Airtable URL from the live page first
- Normalizes Airtable UTC timestamps before applying the configured date filter
- The dashboard subtitle is generated from
data/processed/stats.json, so the displayed range tracks the latest processed snapshot instead of a hard-coded month. - When the live Airtable source is reachable,
python main.pynow captures current layoffs.fyi records, including post-March 2026 entries. - If the live source fails or returns an unusable filtered result, the pipeline falls back to the CSV mirror and then to the bundled offline sample dataset.
- The current snapshot metrics can always be read from
data/processed/stats.json.
The homepage dashboard now combines overview KPIs with additional analysis slices generated from data/processed/:
monthly_comparison.jsonpowers a side-by-side2025 vs 2026monthly comparison chartstage_size_heatmap.jsonpowers aStage ร Layoff Sizeevent heatmaplayoff_pct_distribution.jsonpowers theLayoff % Distributionchartrecent_layoffs.jsonpowers the latest layoff events table shown on the homepage
The pipeline also generates static, crawlable report pages:
trend-report.htmlprovides an indexable trend report with executive summary, key findings, chart-backed sections, methodology, FAQ, and JSON-LD structured data.reports/index.htmlis the archive entry for the planned daily, weekly, monthly, and quarterly report system.reports/weekly/*.htmlincludes the most recent weekly reports and is included insitemap.xml.reports/monthly/*.htmlandreports/quarterly/*.htmlare generated from period report JSON for long-tail SEO.reports/yearly/*.htmlprovides annual and year-to-date summary pages for evergreen SEO.reports/daily/*.htmlis generated only for significant daily reports and usesnoindex, followto avoid thin-content indexing.industries/*.htmlandcountries/*.htmlprovide focused topic pages for long-tail SEO and AI answer discovery.llms.txtandai-summary.jsonprovide GEO-friendly canonical facts for AI answer engines and chatbots.sitemap.xmlis a sitemap index pointing tositemap-main.xml,sitemap-reports.xml, andsitemap-topics.xml.
These pages reuse the existing processed JSON data so they stay aligned with the dashboard after every python main.py run.
- layoffs.fyi โ Primary tech layoff tracker
- RationalFX Annual Reports
- Major tech press: Reuters, Bloomberg, CNBC, The Verge, TechCrunch
- Company press releases and SEC filings
- Scraping:
requests,BeautifulSoup4,lxml - Processing:
pandas - Templating:
Jinja2 - Visualization:
ECharts 5.x(client-side) - Language: Python 3.10+
This project is licensed under the MIT License โ see the LICENSE file for details.
If you found this project useful, please consider giving it a โญ!