A retro Windows 95βstyle timeline of the Internet's IPv4 era. From ARPANET to dual-stack β and beyond. π‘
Curated by IPXO and a growing community of contributors. 500+ milestones, 32 categories, 8 decades of Internet history β rendered in glorious silver-gray panels with beveled borders.
ipv4-events/
βββ docs/ # πΎ Public site root (served by GitHub Pages)
β βββ index.html # Main app β Win95 UI, loads data & renders timeline
β βββ 404.html # Blue Screen of Death 404 page
β βββ CNAME # Custom domain: ipv4.events (apex)
β βββ robots.txt # Crawling rules + sitemap pointer
β βββ sitemap.xml # SEO sitemap (homepage only β SPA canonical)
β βββ icons/ # π±οΈ Win95/98/NT/W2K/XP .ico files + social card
β βββ css/style.css # All styles β retro theme, tabs, filters, modal
β βββ js/app.js # Data fetch, hash routing, filters, render, modal
β βββ data/ # π Human-editable JSON (the real source of truth)
β βββ categories.json # Category IDs / labels / groups / icons
β βββ news.json # Daily news feed (updated by GitHub Actions)
β βββ events/ # Events split by topic
β βββ manifest.json # Load order for all event JSON files
β βββ *.json # One file per category
βββ scripts/
β βββ fetch-news.mjs # π° Fetches RSS feeds β docs/data/news.json
βββ .github/workflows/
βββ fetch-news.yml # βοΈ Runs fetch-news.mjs daily at 06:00 UTCEach event lives in docs/data/events/<category>.json:
{
"id": "1981_rfc791",
"year": 1981,
"categories": ["Standards"],
"title": "RFC 791 β IPv4 Published",
"overview": "The Internet Protocol version 4 (IPv4) is standardized in RFC 791, defining the dominant packet format for decades.",
"hashtags": ["RFC791", "IPv4", "Standards"],
"links": {
"wikipedia": "https://en.wikipedia.org/wiki/IPv4"
}
}| Field | Type | Required | Description |
|---|---|---|---|
id |
string | β | Unique key β lowercase, underscores, no spaces |
year |
integer | β | e.g. 1981 |
categories |
string[] | β | One or more IDs from categories.json |
title |
string | β | Short event title |
overview |
string | β | 2β3 sentences describing the event |
hashtags |
string[] | β | Keywords for search and filtering |
links.wikipedia |
string | βοΈ | Wikipedia article URL |
32 categories organized into 10 groups displayed as a grouped pill bar on the homepage:
| Group | Categories |
|---|---|
| π Standards & Governance | Standards, Governance, RIRs |
| π‘ Networking & Backbone | Networking, Backbone Speeds, Submarine Cables, Wireless, IXPs & NOGs, Hardware & Vendors |
| π» Operating Systems | Windows OS, Linux Distros, Mobile OS |
| π¨βπ» Programming & Software | Programming Languages, Software & Tools, Web Browsers, Streaming & Multimedia |
| π¬ Social & Messaging | Social Networks, Messaging |
| π€ AI & Emerging Tech | Artificial Intelligence, Quantum & Next-Gen, Metaverse & XR |
| π Security & Policy | Security, Policy & Regulation |
| π° Economy | Finance, Market |
| βοΈ Cloud & Infrastructure | Cloud & Virtualization, Serverless, Edge Computing, CDN, Data Centers |
| π Space & Satellite | Satellite Internet, Space |
Each entry in categories.json:
{
"id": "Standards",
"label": "Standards",
"group": "Standards & Governance",
"iconUrl": "icons/w98_help_book_small.ico"
}The easiest way: click "+ Propose an Event" on the homepage β it opens a pre-filled GitHub issue, no fork required.
To contribute JSON directly, read CONTRIBUTING.md.
Pure static HTML + vanilla JS on GitHub Pages β no build step.
npx serve docs
# open http://localhost:3000| File | What it does |
|---|---|
docs/js/app.js |
Parallel data fetch, hash routing, category pill bar, news tab, contribute modal, dynamic meta tags |
docs/css/style.css |
Retro Win95 theme, view tabs, filter controls, decade jump nav, news cards |
docs/data/categories.json |
Canonical category list β edit to add/rename categories |
docs/data/events/manifest.json |
Load order for all event JSON files |
docs/data/news.json |
Auto-generated daily β do not edit by hand |
scripts/fetch-news.mjs |
Fetches RSS from RIPE Labs, APNIC, ARIN, Cloudflare, etc. |
The app uses client-side hash routing. All routes are handled by app.js:
| URL | View |
|---|---|
https://ipv4.events/ |
Timeline, defaults to 2020s |
https://ipv4.events/#/category/networking |
Timeline filtered by category |
https://ipv4.events/#/decade/1990s |
Timeline filtered by decade |
https://ipv4.events/#/search/arpanet |
Timeline filtered by search term |
https://ipv4.events/#/news |
News view |
updatePageMeta() in app.js updates <title> and <meta name="description"> on every route change. This ensures Google's JS-rendering crawl indexes unique titles and descriptions per category, decade, and search view.
CSS and JS are loaded with a ?v= query param in index.html. Bump the version string on every deploy that changes these files:
<link rel="stylesheet" href="css/style.css?v=20260423i">
<script src="js/app.js?v=20260423i" defer></script>The News tab shows the latest articles from IPv4/internet news sources, fetched daily by a GitHub Actions workflow.
Sources: RIPE Labs, APNIC, ARIN, Cloudflare, The Register, IETF, CircleID
Workflow: .github/workflows/fetch-news.yml β runs scripts/fetch-news.mjs daily at 06:00 UTC and commits the result to docs/data/news.json via the GitHub Contents API (signed commit, satisfies branch protection).
To trigger manually: GitHub β Actions β "Fetch news feed" β Run workflow.
This is a pure client-side SPA. SEO approach:
- Single canonical URL β
https://ipv4.events/is the only URL insitemap.xml. Category/decade/news routes are hash-based and not separately indexed. - Dynamic meta tags β
updatePageMeta()sets unique<title>and<meta description>per route for Google's JS-rendering crawl. - HTTPS enforced β GitHub Pages "Enforce HTTPS" is enabled on the repo (Settings β Pages). All
http://requests get a server-side 301 redirect. A JS fallback inindex.htmlhandles edge cases. robots.txtβ references the HTTPS sitemap.- Open Graph + Twitter cards β set in
index.html<head>.
Note: Do not add category or decade URLs back to
sitemap.xml. When Ahrefs (or other crawlers that don't execute JS) encounter these paths, they see thin-content pages and flag them as duplicates, which tanks the health score. TheupdatePageMeta()approach handles SEO for JS-capable crawlers (Google) without creating duplicate-content issues for non-JS crawlers.
- Code: MIT License
- Content: CC BY-SA 4.0 (attribution required)
Made with πΎ by IPXO and contributors.