hide
<script src="
https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<style>
/* Hide the right-hand TOC sidebar and let content use full width */
#toc-sidebar {
display: none !important;
}
.terminal-mkdocs-main-grid {
margin-right: auto;
}
.terminal-mkdocs-main-content {
max-width: 100%;
}
.stats-page {
max-width: 1200px;
margin: 0 auto;
padding: 1rem 0;
font-family: inherit;
}
.stats-header {
text-align: center;
margin-bottom: 2.5rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid #3f3f44;
}
.stats-header img {
height: 48px;
margin-bottom: 0.5rem;
filter: drop-shadow(0 0 12px rgba(80, 255, 255, 0.3));
}
.stats-header h1 {
font-size: 1.8rem;
color: #e8e9ed;
margin: 0.5rem 0 0.25rem;
letter-spacing: 0.5px;
}
.stats-header .subtitle {
color: #a3abba;
font-size: 0.95rem;
}
/* Metric Cards */
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-bottom: 2.5rem;
}
.metric-card {
background: #1a1a1a;
border: 1px solid #3f3f44;
border-radius: 10px;
padding: 1.25rem;
text-align: center;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.metric-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, #50ffff, #f380f5);
opacity: 0;
transition: opacity 0.3s ease;
}
.metric-card:hover {
transform: translateY(-4px);
border-color: #50ffff;
box-shadow: 0 8px 24px rgba(80, 255, 255, 0.12);
}
.metric-card:hover::before {
opacity: 1;
}
.metric-value {
font-size: 2rem;
font-weight: 700;
color: #50ffff;
margin: 0.25rem 0;
line-height: 1.2;
}
.metric-label {
font-size: 0.8rem;
color: #a3abba;
text-transform: uppercase;
letter-spacing: 1px;
}
.metric-sublabel {
font-size: 0.75rem;
color: #3f3f44;
margin-top: 0.25rem;
}
/* Chart Sections */
.chart-section {
background: #1a1a1a;
border: 1px solid #3f3f44;
border-radius: 10px;
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.chart-section h2 {
font-size: 1.1rem;
color: #e8e9ed;
margin: 0 0 1rem 0;
padding-bottom: 0.75rem;
border-bottom: 1px solid #3f3f44;
}
.chart-container {
position: relative;
width: 100%;
height: 350px;
}
.chart-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
margin-bottom: 1.5rem;
}
@media (max-width: 768px) {
.stats-page {
padding: 0.5rem 0.75rem;
}
.stats-header h1 {
font-size: 1.4rem;
}
.chart-row {
grid-template-columns: 1fr;
}
.metrics-grid {
grid-template-columns: repeat(2, 1fr);
gap: 0.6rem;
}
.metric-card {
padding: 0.9rem 0.5rem;
}
.metric-value {
font-size: 1.5rem;
}
.metric-label {
font-size: 0.7rem;
}
.chart-container {
height: 260px;
}
.chart-section {
padding: 1rem;
}
}
@media (max-width: 480px) {
.metrics-grid {
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
}
.metric-value {
font-size: 1.25rem;
}
.metric-label {
font-size: 0.65rem;
letter-spacing: 0.5px;
}
.metric-sublabel {
font-size: 0.65rem;
}
.chart-container {
height: 220px;
}
.chart-section h2 {
font-size: 0.95rem;
}
}
/* Footer */
.stats-footer {
text-align: center;
padding: 1.5rem 0;
margin-top: 1rem;
border-top: 1px solid #3f3f44;
color: #a3abba;
font-size: 0.8rem;
}
</style>
Growth
Community growth & adoption metrics for Crawl4AI
GitHub Stars
60,904
stargazers
Monthly Downloads
914.2K
PyPI · latest month
Total Downloads
9.72M
PyPI cumulative
Docker Pulls
1.41M
hub.docker.com
Forks / Contributors
6,217 / 57
GitHub
Cumulative PyPI Downloads
Updated February 24, 2026 · Data from GitHub API, PyPI Stats, Docker Hub
<script>
// --- Chart.js Global Config ---
Chart.defaults.color = '#a3abba';
Chart.defaults.borderColor = '#3f3f44';
Chart.defaults.font.family = "'dm', Monaco, 'Courier New', monospace";
const CYAN = '#50ffff';
const CYAN_DIM = 'rgba(80,255,255,0.10)';
const CYAN_HOVER = '#0fbbaa';
const PINK = '#f380f5';
const PINK_DIM = 'rgba(243,128,245,0.10)';
const GRID_COLOR = '#3f3f44';
const TOOLTIP_BG = '#1a1a1a';
const tooltipStyle = {
backgroundColor: TOOLTIP_BG,
borderColor: CYAN,
borderWidth: 1,
titleColor: '#e8e9ed',
bodyColor: '#a3abba',
padding: 10,
cornerRadius: 6,
displayColors: false,
};
const gridStyle = { color: GRID_COLOR, drawBorder: false };
const tickStyle = { color: '#a3abba', font: { size: 11 } };
// --- Data ---
const monthlyLabels = ["2024-09", "2024-10", "2024-11", "2024-12", "2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08", "2025-09", "2025-10", "2025-11", "2025-12", "2026-01", "2026-02"];
const monthlyValues = [28000, 135000, 210000, 285000, 350000, 380000, 430000, 480000, 520000, 560000, 620000, 750000, 836245, 911467, 726475, 657370, 922296, 914168];
const starDates = ["2024-02-01", "2024-06-01", "2024-09-01", "2024-10-01", "2024-11-01", "2024-12-01", "2025-01-01", "2025-02-01", "2025-03-01", "2025-04-01", "2025-05-01", "2025-06-01", "2025-07-01", "2025-08-01", "2025-09-01", "2025-10-01", "2025-11-01", "2025-12-01", "2026-01-01", "2026-02-24"];
const starCounts = [0, 2000, 5000, 12000, 18000, 22000, 26000, 30000, 34000, 38000, 42000, 45000, 47000, 49000, 51000, 53000, 55000, 57000, 59000, 60904];
const cumulativeLabels = ["2024-09", "2024-10", "2024-11", "2024-12", "2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08", "2025-09", "2025-10", "2025-11", "2025-12", "2026-01", "2026-02"];
const cumulativePypi = [28000, 163000, 373000, 658000, 1008000, 1388000, 1818000, 2298000, 2818000, 3378000, 3998000, 4748000, 5584245, 6495712, 7222187, 7879557, 8801853, 9716021];
const dailyLabels = ["2025-08-27", "2025-08-28", "2025-08-29", "2025-08-30", "2025-08-31", "2025-09-01", "2025-09-02", "2025-09-03", "2025-09-04", "2025-09-05", "2025-09-06", "2025-09-07", "2025-09-08", "2025-09-09", "2025-09-10", "2025-09-11", "2025-09-12", "2025-09-13", "2025-09-14", "2025-09-15", "2025-09-16", "2025-09-17", "2025-09-18", "2025-09-19", "2025-09-20", "2025-09-21", "2025-09-22", "2025-09-23", "2025-09-24", "2025-09-25", "2025-09-26", "2025-09-27", "2025-09-28", "2025-09-29", "2025-09-30", "2025-10-01", "2025-10-02", "2025-10-03", "2025-10-04", "2025-10-05", "2025-10-06", "2025-10-07", "2025-10-08", "2025-10-09", "2025-10-10", "2025-10-11", "2025-10-12", "2025-10-13", "2025-10-14", "2025-10-15", "2025-10-16", "2025-10-17", "2025-10-18", "2025-10-19", "2025-10-20", "2025-10-21", "2025-10-22", "2025-10-23", "2025-10-24", "2025-10-25", "2025-10-26", "2025-10-27", "2025-10-28", "2025-10-29", "2025-10-30", "2025-10-31", "2025-11-01", "2025-11-02", "2025-11-03", "2025-11-04", "2025-11-05", "2025-11-06", "2025-11-07", "2025-11-08", "2025-11-09", "2025-11-10", "2025-11-11", "2025-11-12", "2025-11-13", "2025-11-14", "2025-11-15", "2025-11-16", "2025-11-17", "2025-11-18", "2025-11-19", "2025-11-20", "2025-11-21", "2025-11-22", "2025-11-23", "2025-11-24", "2025-11-25", "2025-11-26", "2025-11-27", "2025-11-28", "2025-11-29", "2025-11-30", "2025-12-01", "2025-12-02", "2025-12-03", "2025-12-04", "2025-12-05", "2025-12-06", "2025-12-07", "2025-12-08", "2025-12-09", "2025-12-10", "2025-12-11", "2025-12-12", "2025-12-13", "2025-12-14", "2025-12-15", "2025-12-16", "2025-12-17", "2025-12-18", "2025-12-19", "2025-12-20", "2025-12-21", "2025-12-22", "2025-12-23", "2025-12-24", "2025-12-25", "2025-12-26", "2025-12-27", "2025-12-28", "2025-12-29", "2025-12-30", "2025-12-31", "2026-01-01", "2026-01-02", "2026-01-03", "2026-01-04", "2026-01-05", "2026-01-06", "2026-01-07", "2026-01-08", "2026-01-09", "2026-01-10", "2026-01-11", "2026-01-12", "2026-01-13", "2026-01-14", "2026-01-15", "2026-01-16", "2026-01-17", "2026-01-18", "2026-01-19", "2026-01-20", "2026-01-21", "2026-01-22", "2026-01-23", "2026-01-24", "2026-01-25", "2026-01-26", "2026-01-27", "2026-01-28", "2026-01-29", "2026-01-30", "2026-01-31", "2026-02-01", "2026-02-02", "2026-02-03", "2026-02-04", "2026-02-05", "2026-02-06", "2026-02-07", "2026-02-08", "2026-02-09", "2026-02-10", "2026-02-11", "2026-02-12", "2026-02-13", "2026-02-14", "2026-02-15", "2026-02-16", "2026-02-17", "2026-02-18", "2026-02-19", "2026-02-20", "2026-02-21", "2026-02-22", "2026-02-23"];
const dailyValues = [36852, 29139, 26202, 14515, 12717, 30212, 26723, 36263, 30947, 21856, 12788, 16109, 33670, 38096, 38520, 32210, 32645, 16740, 15665, 33468, 35826, 37881, 38822, 34382, 12228, 15941, 34119, 32959, 33236, 29592, 27001, 14190, 11923, 28881, 33352, 29133, 22553, 20377, 10201, 18760, 28627, 26443, 33205, 30002, 37306, 24336, 19082, 28941, 27498, 36493, 30912, 28221, 26990, 41450, 69663, 45509, 37775, 30266, 24564, 12144, 14088, 28156, 32380, 32150, 32103, 32139, 15927, 14829, 25046, 34682, 36734, 24177, 27621, 18836, 17588, 23041, 24663, 32488, 35575, 24627, 11902, 22698, 26320, 27062, 33285, 28878, 37767, 14090, 13125, 25697, 28261, 32016, 25571, 22364, 11104, 10501, 23124, 25857, 24070, 27150, 22595, 12676, 18075, 25277, 33018, 33318, 26019, 21790, 11025, 12901, 21774, 29209, 32380, 24685, 22711, 22882, 13627, 22852, 20014, 23430, 12401, 14902, 11492, 12861, 18941, 19171, 17143, 11321, 16012, 13309, 14477, 28824, 28074, 25749, 26326, 32618, 25266, 31603, 33214, 40930, 34411, 34820, 32173, 23178, 29160, 46329, 34716, 37425, 39073, 36770, 20527, 25662, 33863, 37671, 43628, 34239, 29112, 21816, 28222, 41988, 57712, 43590, 43377, 38494, 27584, 26270, 36057, 51525, 48067, 47749, 42424, 29999, 28833, 43076, 39635, 42221, 42354, 43540, 38995, 32268, 40188];
const trafficDates = ["2026-02-10", "2026-02-11", "2026-02-12", "2026-02-13", "2026-02-14", "2026-02-15", "2026-02-16", "2026-02-17", "2026-02-18", "2026-02-19", "2026-02-20", "2026-02-21", "2026-02-22", "2026-02-23"];
const trafficViews = [3012, 5764, 4431, 1974, 2246, 1647, 1627, 2638, 4650, 5464, 3370, 2275, 2702, 4372];
const trafficUniques = [1698, 2863, 2082, 1014, 1098, 1014, 1093, 1597, 1610, 1554, 1374, 1182, 1595, 2344];
function shortMonth(label) {
const parts = label.split('-');
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return months[parseInt(parts[1])-1] + ' ' + parts[0].slice(2);
}
function shortDate(label) {
const parts = label.split('-');
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return months[parseInt(parts[1])-1] + ' ' + parts[2];
}
function fmtK(val) {
if (val >= 1000000) return (val/1000000).toFixed(1) + 'M';
if (val >= 1000) return (val/1000).toFixed(0) + 'K';
return val;
}
// --- Chart 1: Monthly Downloads (bar) ---
new Chart(document.getElementById('monthlyChart'), {
type: 'bar',
data: {
labels: monthlyLabels.map(shortMonth),
datasets: [{
label: 'Downloads',
data: monthlyValues,
backgroundColor: CYAN,
hoverBackgroundColor: CYAN_HOVER,
borderRadius: 4,
borderSkipped: false,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { ...tooltipStyle, callbacks: { label: ctx => fmtK(ctx.raw) + ' downloads' } }
},
scales: {
x: { grid: { display: false }, ticks: tickStyle },
y: { grid: gridStyle, ticks: { ...tickStyle, callback: fmtK } }
}
}
});
// --- Chart 2: Star Growth (area) ---
new Chart(document.getElementById('starsChart'), {
type: 'line',
data: {
labels: starDates.map(shortMonth),
datasets: [{
label: 'Stars',
data: starCounts,
borderColor: CYAN,
backgroundColor: CYAN_DIM,
fill: true,
tension: 0.35,
pointRadius: 3,
pointBackgroundColor: CYAN,
pointHoverRadius: 6,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { ...tooltipStyle, callbacks: { label: ctx => fmtK(ctx.raw) + ' stars' } }
},
scales: {
x: { grid: { display: false }, ticks: { ...tickStyle, maxTicksLimit: 8 } },
y: { grid: gridStyle, ticks: { ...tickStyle, callback: fmtK } }
}
}
});
// --- Chart 3: Cumulative Downloads (area) ---
new Chart(document.getElementById('cumulativeChart'), {
type: 'line',
data: {
labels: cumulativeLabels.map(shortMonth),
datasets: [{
label: 'Cumulative PyPI',
data: cumulativePypi,
borderColor: PINK,
backgroundColor: PINK_DIM,
fill: true,
tension: 0.35,
pointRadius: 3,
pointBackgroundColor: PINK,
pointHoverRadius: 6,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { ...tooltipStyle, callbacks: { label: ctx => fmtK(ctx.raw) + ' total downloads' } }
},
scales: {
x: { grid: { display: false }, ticks: tickStyle },
y: { grid: gridStyle, ticks: { ...tickStyle, callback: fmtK } }
}
}
});
// --- Chart 4: Daily Downloads (area) ---
(function() {
// Sample daily data to avoid overcrowding (show every 7th day)
const step = Math.max(1, Math.floor(dailyLabels.length / 60));
const sampledLabels = dailyLabels.filter((_, i) => i % step === 0);
const sampledValues = dailyValues.filter((_, i) => i % step === 0);
new Chart(document.getElementById('dailyChart'), {
type: 'line',
data: {
labels: sampledLabels.map(shortDate),
datasets: [{
label: 'Daily Downloads',
data: sampledValues,
borderColor: CYAN,
backgroundColor: CYAN_DIM,
fill: true,
tension: 0.3,
pointRadius: 0,
borderWidth: 1.5,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { ...tooltipStyle, callbacks: { label: ctx => fmtK(ctx.raw) + ' downloads' } }
},
scales: {
x: { grid: { display: false }, ticks: { ...tickStyle, maxTicksLimit: 8 } },
y: { grid: gridStyle, ticks: { ...tickStyle, callback: fmtK }, beginAtZero: true }
}
}
});
})();
// --- Chart 5: GitHub Traffic (dual bar) ---
new Chart(document.getElementById('trafficChart'), {
type: 'bar',
data: {
labels: trafficDates.map(shortDate),
datasets: [
{
label: 'Page Views',
data: trafficViews,
backgroundColor: CYAN,
hoverBackgroundColor: CYAN_HOVER,
borderRadius: 4,
borderSkipped: false,
},
{
label: 'Unique Visitors',
data: trafficUniques,
backgroundColor: PINK,
hoverBackgroundColor: '#d060d0',
borderRadius: 4,
borderSkipped: false,
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: { color: '#a3abba', boxWidth: 12, padding: 16 }
},
tooltip: tooltipStyle,
},
scales: {
x: { grid: { display: false }, ticks: tickStyle },
y: { grid: gridStyle, ticks: tickStyle }
}
}
});
</script>