firecrawl/pdf-inspectorPublic

Fast Rust library for PDF inspection, classification, and text extraction. Intelligently detects scanned vs text-based PDFs to enable smart routing decisions.

AI summary: A fast Rust library for PDF classification, text extraction, and Markdown conversion without relying on expensive OCR.

Stars
12.9K
+761 today
Forks
872
Watchers
31
Open issues
26
Open PRs
37
Contributors
~6
Commits
416
Branches
112

RustMITCreated Feb 6, 2026Last push today+3K stars this week+3K this month

Star history

since Feb 8, 2026
05K10KFeb 2026Apr 2026Jun 2026Aug 2026
12.9K stars as of Aug 7, 2026, tracked back to Feb 8, 2026. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
AugSepOctNovDecJanFebMarAprMayJunJulAugMonWedFri2025-08-09: 0 commits2025-08-10: 0 commits2025-08-11: 0 commits2025-08-12: 0 commits2025-08-13: 0 commits2025-08-14: 0 commits2025-08-15: 0 commits2025-08-16: 0 commits2025-08-17: 0 commits2025-08-18: 0 commits2025-08-19: 0 commits2025-08-20: 0 commits2025-08-21: 0 commits2025-08-22: 0 commits2025-08-23: 0 commits2025-08-24: 0 commits2025-08-25: 0 commits2025-08-26: 0 commits2025-08-27: 0 commits2025-08-28: 0 commits2025-08-29: 0 commits2025-08-30: 0 commits2025-08-31: 0 commits2025-09-01: 0 commits2025-09-02: 0 commits2025-09-03: 0 commits2025-09-04: 0 commits2025-09-05: 0 commits2025-09-06: 0 commits2025-09-07: 0 commits2025-09-08: 0 commits2025-09-09: 0 commits2025-09-10: 0 commits2025-09-11: 0 commits2025-09-12: 0 commits2025-09-13: 0 commits2025-09-14: 0 commits2025-09-15: 0 commits2025-09-16: 0 commits2025-09-17: 0 commits2025-09-18: 0 commits2025-09-19: 0 commits2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 6 commits2026-02-07: 16 commits2026-02-08: 2 commits2026-02-09: 5 commits2026-02-10: 1 commit2026-02-11: 7 commits2026-02-12: 5 commits2026-02-13: 8 commits2026-02-14: 5 commits2026-02-15: 5 commits2026-02-16: 12 commits2026-02-17: 13 commits2026-02-18: 11 commits2026-02-19: 2 commits2026-02-20: 9 commits2026-02-21: 2 commits2026-02-22: 1 commit2026-02-23: 6 commits2026-02-24: 1 commit2026-02-25: 5 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 1 commit2026-03-03: 4 commits2026-03-04: 6 commits2026-03-05: 6 commits2026-03-06: 1 commit2026-03-07: 2 commits2026-03-08: 0 commits2026-03-09: 6 commits2026-03-10: 0 commits2026-03-11: 5 commits2026-03-12: 5 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 4 commits2026-03-18: 8 commits2026-03-19: 5 commits2026-03-20: 5 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 7 commits2026-03-24: 2 commits2026-03-25: 7 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 30 commits2026-04-03: 1 commit2026-04-04: 21 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 5 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 2 commits2026-04-12: 0 commits2026-04-13: 5 commits2026-04-14: 7 commits2026-04-15: 2 commits2026-04-16: 1 commit2026-04-17: 6 commits2026-04-18: 0 commits2026-04-19: 1 commit2026-04-20: 8 commits2026-04-21: 3 commits2026-04-22: 2 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 3 commits2026-04-27: 6 commits2026-04-28: 2 commits2026-04-29: 3 commits2026-04-30: 1 commit2026-05-01: 0 commits2026-05-02: 2 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 1 commit2026-05-07: 2 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 5 commits2026-05-13: 0 commits2026-05-14: 6 commits2026-05-15: 1 commit2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 1 commit2026-05-19: 0 commits2026-05-20: 1 commit2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 1 commit2026-05-28: 1 commit2026-05-29: 1 commit2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 2 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 3 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 1 commit2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 2 commits2026-06-24: 3 commits2026-06-25: 0 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 0 commits2026-06-30: 0 commits2026-07-01: 0 commits2026-07-02: 0 commits2026-07-03: 0 commits2026-07-04: 0 commits2026-07-05: 0 commits2026-07-06: 0 commits2026-07-07: 0 commits2026-07-08: 2 commits2026-07-09: 1 commit2026-07-10: 9 commits2026-07-11: 8 commits2026-07-12: 0 commits2026-07-13: 2 commits2026-07-14: 16 commits2026-07-15: 12 commits2026-07-16: 8 commits2026-07-17: 2 commits2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 0 commits2026-07-21: 0 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 0 commits2026-07-25: 0 commits2026-07-26: 0 commits2026-07-27: 0 commits2026-07-28: 0 commits2026-07-29: 0 commits2026-07-30: 0 commits2026-07-31: 6 commits2026-08-01: 0 commits2026-08-02: 0 commits2026-08-03: 4 commits2026-08-04: 1 commit2026-08-05: 0 commits2026-08-06: 0 commits2026-08-07: 0 commits2026-08-08: 0 commits
409 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Widely adopted

    12,943 stars

  • Rising fast

    +3,018 stars this week

  • Actively maintained

    Pushed within 48 hours

  • Permissive license

    MIT

  • Repeat trending

    4 trending appearances

What pdf-inspector does

pdf-inspector is a lightweight, pure Rust tool designed to efficiently process native-text PDFs locally in under 200ms. It intelligently detects whether a PDF is text-based or scanned using content stream sampling, allowing developers to skip costly OCR services for over half of standard documents. The library extracts text with precise font and coordinate awareness, detecting multi-column reading orders automatically. It then converts this structured data into clean Markdown, reliably recognizing headings, lists, code blocks, and dual-mode tables (rectangle-based and heuristic) while handling complex CID fonts.

Data engineers, backend developers, and ML practitioners who need to process large volumes of PDF documents efficiently and securely. It is ideal for teams that want to minimize expensive OCR usage and can leverage Rust, Python, Node.js, or WebAssembly.

  • Smart classification: Quickly detects TextBased, Scanned, ImageBased, or Mixed PDFs by sampling content streams, providing a confidence score and per-page routing.
  • Text extraction: Provides highly position-aware text extraction that includes font information, X/Y coordinates, and sequential multi-column reading order detection.
  • Markdown conversion: Automatically translates PDF elements into clean Markdown, including tiered headings based on font size ratios, various list types, and formatted text.
  • Table detection: Utilizes a dual-mode approach combining rectangle-based detection from drawing operations with heuristic detection from text alignment to handle complex financial data.
  • CID font support: Seamlessly decodes ToUnicode CMaps for challenging Type0/Identity-H fonts, natively supporting UTF-16BE, UTF-8, and Latin-1 text encodings.
  • Browser WebAssembly: Runs the exact same Rust parser locally within browsers and Web Workers with embedded CMaps, entirely eliminating server round trips.

Where teams use it

Local Research Data Pipeline

Ingest thousands of research papers into a vector database locally using standard Node.js or Python bindings, relying on the parser to output clean Markdown without sending data to external APIs.

Financial Report Processing

Extract structured tables and numerical data from complex, multi-column corporate financial PDFs by leveraging the dual-mode rectangle and heuristic table detection.

Client-Side Document Inspection

Use the WebAssembly bindings in a web application to instantly analyze uploaded PDFs in the user's browser, flagging image-only scanned files that require backend OCR.

Automated Invoice Parsing

Quickly convert natively generated digital invoices and receipts into structured Markdown using the CLI tool in a bash script, keeping token output efficient for downstream LLM parsing.

Getting started: npm install @firecrawl/pdf-inspector

README

main branch

pdf-inspector

Crates.io npm PyPI License: MIT

Fast Rust library for PDF classification and text extraction. Detects whether a PDF is text-based or scanned, extracts text with position awareness, and converts to clean Markdown — all without OCR. Includes bindings for Python, Node.js, and browser WebAssembly.

Built by Firecrawl to handle text-based PDFs locally in under 200ms, skipping expensive OCR services for the ~54% of PDFs that don't need them.

Features

  • Smart classification — Detect TextBased, Scanned, ImageBased, or Mixed PDFs in ~10-50ms by sampling content streams. Returns a confidence score (0.0-1.0) and per-page OCR routing.
  • Text extraction — Position-aware extraction with font info, X/Y coordinates, and automatic multi-column reading order.
  • Markdown conversion — Headings (H1-H4 via font size ratios), bullet/numbered/letter lists, code blocks (monospace font detection), tables (rectangle-based and heuristic), bold/italic formatting, URL linking, and page breaks.
  • Table detection — Dual-mode: rectangle-based detection from PDF drawing ops, plus heuristic detection from text alignment. Handles financial tables, footnotes, and continuation tables across pages.
  • CID font support — ToUnicode CMap decoding for Type0/Identity-H fonts, UTF-16BE, UTF-8, and Latin-1 encodings.
  • Multi-column layout — Automatic detection of newspaper-style columns, sequential reading order, and RTL text support.
  • Encoding issue detection — Automatically flags broken font encodings so callers can fall back to OCR.
  • Single document load — The document is parsed once and shared between detection and extraction, avoiding redundant I/O.
  • Browser WebAssembly — Run the same Rust parser locally in browsers and Web Workers, with embedded CMaps and no server round trip.
  • Lightweight — Pure Rust, no ML models, no external services. Single dependency on lopdf for PDF parsing.

Benchmark

Evaluated on the opendataloader-bench corpus (200 PDFs). Only local engines without model-based PDF parsing are shown; OCR was disabled. Scores are 0-1, higher is better.

Engine Overall Reading Order (NID) Tables (TEDS) Headings (MHS) Speed (200 docs)
pdf-inspector 0.875 0.915 0.814 0.788 0.470s
liteparse 0.873 0.913 0.693 0.811 0.750s
opendataloader 0.831 0.902 0.489 0.739 2.569s
pymupdf4llm 0.735 0.886 0.401 0.424 17.117s
markitdown 0.589 0.844 0.273 0.000 16.165s

Results were refreshed on July 31, 2026, on an Apple M4 Pro. Engine versions were pdf-inspector 0.2.6, LiteParse 2.10.1, OpenDataLoader 2.2.1, PyMuPDF4LLM 0.2.0, and MarkItDown 0.1.5. Speed is the median of five alternating or rotating complete corpus runs after an excluded warm-up run, with each parser processing documents sequentially in a single process.

The complete parser configuration, per-document predictions, evaluator output, and generated charts are available in the reproducible results branch.

Best fit: Native-text PDFs where speed, reading order, and table structure matter. In this comparison, pdf-inspector delivered the higher overall, reading-order, and table scores, along with the fastest complete run. That makes it a strong local default for reports, research papers, financial documents, invoices, and legal PDFs that need clean, structured Markdown without adding OCR latency or infrastructure.

Use the paired benchmark harness to compare two local builds against the exact same corpus and evaluator revision.

Quick start

Python

pip install maturin
maturin develop --release
import pdf_inspector

result = pdf_inspector.process_pdf("document.pdf")
print(result.pdf_type)   # "text_based", "scanned", "image_based", "mixed"
print(result.markdown)   # Markdown string or None

Full API reference: docs/python.md

Node.js

npm install @firecrawl/pdf-inspector
import { readFileSync } from 'fs';
import { processPdf, classifyPdf } from '@firecrawl/pdf-inspector';

const result = processPdf(readFileSync('document.pdf'));
console.log(result.pdfType);   // "TextBased", "Scanned", "ImageBased", "Mixed"
console.log(result.markdown);  // Markdown string or null

Full API reference: napi/README.md

Browser WebAssembly

npm install @firecrawl/pdf-inspector-wasm
import init, { processPdf } from '@firecrawl/pdf-inspector-wasm';

await init();
const response = await fetch('/document.pdf');
const pdf = new Uint8Array(await response.arrayBuffer());
const result = processPdf(pdf);

console.log(result.pdfType);
console.log(result.markdown);

Full API reference: wasm/README.md

Rust

Install from crates.io:

cargo add pdf-inspector

Or add it manually:

[dependencies]
pdf-inspector = "0.1"
use pdf_inspector::process_pdf;

let result = process_pdf("document.pdf")?;
println!("Type: {:?}", result.pdf_type);
if let Some(markdown) = &result.markdown {
    println!("{}", markdown);
}

Full API reference: docs/rust-api.md

CLI

# Install the CLI tools
cargo install pdf-inspector

# Convert PDF to Markdown
pdf2md document.pdf

# JSON output (for piping)
pdf2md document.pdf --json

# Positioned TextItem JSON, including is_underline metadata
pdf2md document.pdf --items-json

# Raw markdown only (no headers)
pdf2md document.pdf --raw

# Token-efficient output (collapses long dot leaders and similar source padding)
pdf2md document.pdf --compact

# Insert page break markers (<!-- Page N -->)
pdf2md document.pdf --pages

# Process only specific pages
pdf2md document.pdf --select-pages 1,3,5-10

# Detection only (no extraction)
detect-pdf document.pdf
detect-pdf document.pdf --json

# Detection + layout analysis (tables, columns)
detect-pdf document.pdf --analyze --json

From a source checkout, use cargo run --bin pdf2md -- document.pdf or cargo run --bin detect-pdf -- document.pdf instead.

Architecture

PDF bytes
  │
  ├─► detector         → PdfType (TextBased / Scanned / ImageBased / Mixed)
  │
  └─► extractor
        ├─ fonts        → font widths, encodings
        ├─ content_stream → walk PDF operators → TextItems + PdfRects
        ├─ xobjects     → Form XObject text, image placeholders
        ├─ links        → hyperlinks, AcroForm fields
        └─ layout       → column detection → line grouping → reading order
              │
              ├─► tables
              │     ├─ detect_rects      → rectangle-based tables (union-find)
              │     ├─ detect_heuristic  → alignment-based tables
              │     ├─ grid              → column/row assignment → cells
              │     └─ format            → cells → Markdown table
              │
              └─► markdown
                    ├─ analysis     → font stats, heading tiers
                    ├─ preprocess   → merge headings, drop caps
                    ├─ convert      → line loop + table/image insertion
                    ├─ classify     → captions, lists, code
                    └─ postprocess  → cleanup → final Markdown

The document is loaded once via load_document_from_path / load_document_from_mem and shared between the detection and extraction stages, so there's no redundant parsing.

Project structure

src/
  lib.rs                — Public API, PdfOptions builder, convenience functions
  python.rs             — PyO3 Python bindings
  types.rs              — Shared types: TextItem, TextLine, PdfRect, ItemType
  text_utils.rs         — Character/text helpers (CJK, RTL, ligatures, bold/italic)
  process_mode.rs       — ProcessMode enum (DetectOnly, Analyze, Full)
  detector.rs           — Fast PDF type detection without full document load
  glyph_names.rs        — Adobe Glyph List → Unicode mapping
  tounicode.rs          — ToUnicode CMap parsing for CID-encoded text
  extractor/            — Text extraction pipeline
  tables/               — Table detection and formatting
  markdown/             — Markdown conversion and structure detection
  bin/                  — CLI tools (pdf2md, detect_pdf)
napi/                   — Node.js/Bun bindings (napi-rs)
wasm/                   — Browser bindings (wasm-bindgen)

How classification works

  1. Parse the xref table and page tree (no full object load)
  2. Select pages based on ScanStrategy (default: all pages with early exit)
  3. Look for Tj/TJ (text operators) and Do (image operators) in content streams
  4. Classify based on text operator presence across sampled pages

This detects 300+ page PDFs in milliseconds. The result includes pages_needing_ocr — a list of specific page numbers that lack text, enabling per-page OCR routing instead of all-or-nothing.

Scan strategies

Strategy Behavior Best for
EarlyExit (default) Scan all pages, stop on first non-text page Pipelines routing TextBased PDFs to fast extraction
Full Scan all pages, no early exit Accurate Mixed vs Scanned classification
Sample(n) Sample n evenly distributed pages (first, last, middle) Very large PDFs where speed matters more than precision
Pages(vec) Only scan specific 1-indexed page numbers When the caller knows which pages to check

Markdown output

The converter handles:

Element How it's detected
Headings (H1-H4) Font size tiers relative to body text, with 0.5pt clustering
Bold/italic Font name patterns (Bold, Italic, Oblique)
Bullet lists *, -, *, , , prefixes
Numbered lists 1., 1), (1) patterns
Letter lists a., a), (a) patterns
Code blocks Monospace fonts (Courier, Consolas, Monaco, Menlo, Fira Code, JetBrains Mono) and keyword detection
Tables Rectangle-based detection from PDF drawing ops + heuristic detection from text alignment
Financial tables Token splitting for consolidated numeric values
Captions "Figure", "Table", "Source:" prefix detection
Sub/superscript Font size and Y-offset relative to baseline
URLs Converted to Markdown links
Hyphenation Rejoins words broken across lines
Page numbers Filtered from output
Drop caps Large initial letters merged with following text
Dot leaders TOC-style dots collapsed to " ... "

Use case: smart PDF routing

pdf-inspector was built for pipelines that process PDFs at scale. Instead of sending every PDF through OCR:

PDF arrives
  → pdf-inspector classifies it (~20ms)
  → TextBased + high confidence?
      YES → extract locally (~150ms), done
      NO  → send to OCR service (2-10s)

This saves cost and latency for the majority of PDFs that are already text-based (reports, papers, invoices, legal docs).

Debugging

See docs/debugging.md for RUST_LOG environment variable usage.

License

MIT

View on GitHub

Recent activity

commits and pull requests

Commits per week

last 52 weeks
540Week of 2025-08-09: 0 commitsWeek of 2025-08-16: 0 commitsWeek of 2025-08-23: 0 commitsWeek of 2025-08-30: 0 commitsWeek of 2025-09-06: 0 commitsWeek of 2025-09-13: 0 commitsWeek of 2025-09-20: 0 commitsWeek of 2025-09-27: 0 commitsWeek of 2025-10-04: 0 commitsWeek of 2025-10-11: 0 commitsWeek of 2025-10-18: 0 commitsWeek of 2025-10-25: 0 commitsWeek of 2025-11-01: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 22 commitsWeek of 2026-02-08: 33 commitsWeek of 2026-02-15: 54 commitsWeek of 2026-02-22: 13 commitsWeek of 2026-03-01: 20 commitsWeek of 2026-03-08: 16 commitsWeek of 2026-03-15: 22 commitsWeek of 2026-03-22: 16 commitsWeek of 2026-03-29: 52 commitsWeek of 2026-04-05: 7 commitsWeek of 2026-04-12: 21 commitsWeek of 2026-04-19: 14 commitsWeek of 2026-04-26: 17 commitsWeek of 2026-05-03: 3 commitsWeek of 2026-05-10: 12 commitsWeek of 2026-05-17: 2 commitsWeek of 2026-05-24: 3 commitsWeek of 2026-05-31: 5 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 1 commitsWeek of 2026-06-21: 5 commitsWeek of 2026-06-28: 0 commitsWeek of 2026-07-05: 20 commitsWeek of 2026-07-12: 40 commitsWeek of 2026-07-19: 0 commitsWeek of 2026-07-26: 6 commitsWeek of 2026-08-02: 5 commitsAug 9, 2025Aug 2, 2026
409 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 1 commitsSun 1:00 — 0 commitsSun 2:00 — 0 commitsSun 3:00 — 0 commitsSun 4:00 — 0 commitsSun 5:00 — 0 commitsSun 6:00 — 0 commitsSun 7:00 — 0 commitsSun 8:00 — 0 commitsSun 9:00 — 1 commitsSun 10:00 — 0 commitsSun 11:00 — 0 commitsSun 12:00 — 0 commitsSun 13:00 — 0 commitsSun 14:00 — 0 commitsSun 15:00 — 0 commitsSun 16:00 — 1 commitsSun 17:00 — 1 commitsSun 18:00 — 0 commitsSun 19:00 — 1 commitsSun 20:00 — 0 commitsSun 21:00 — 4 commitsSun 22:00 — 2 commitsSun 23:00 — 1 commitsMon 0:00 — 0 commitsMon 1:00 — 0 commitsMon 2:00 — 0 commitsMon 3:00 — 0 commitsMon 4:00 — 0 commitsMon 5:00 — 0 commitsMon 6:00 — 0 commitsMon 7:00 — 0 commitsMon 8:00 — 4 commitsMon 9:00 — 9 commitsMon 10:00 — 9 commitsMon 11:00 — 4 commitsMon 12:00 — 4 commitsMon 13:00 — 3 commitsMon 14:00 — 7 commitsMon 15:00 — 3 commitsMon 16:00 — 3 commitsMon 17:00 — 4 commitsMon 18:00 — 4 commitsMon 19:00 — 3 commitsMon 20:00 — 1 commitsMon 21:00 — 3 commitsMon 22:00 — 4 commitsMon 23:00 — 0 commitsTue 0:00 — 2 commitsTue 1:00 — 1 commitsTue 2:00 — 0 commitsTue 3:00 — 0 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 0 commitsTue 7:00 — 0 commitsTue 8:00 — 2 commitsTue 9:00 — 3 commitsTue 10:00 — 3 commitsTue 11:00 — 4 commitsTue 12:00 — 4 commitsTue 13:00 — 6 commitsTue 14:00 — 1 commitsTue 15:00 — 1 commitsTue 16:00 — 4 commitsTue 17:00 — 5 commitsTue 18:00 — 8 commitsTue 19:00 — 5 commitsTue 20:00 — 3 commitsTue 21:00 — 5 commitsTue 22:00 — 4 commitsTue 23:00 — 0 commitsWed 0:00 — 1 commitsWed 1:00 — 4 commitsWed 2:00 — 0 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 0 commitsWed 6:00 — 0 commitsWed 7:00 — 0 commitsWed 8:00 — 3 commitsWed 9:00 — 3 commitsWed 10:00 — 8 commitsWed 11:00 — 9 commitsWed 12:00 — 5 commitsWed 13:00 — 12 commitsWed 14:00 — 4 commitsWed 15:00 — 7 commitsWed 16:00 — 6 commitsWed 17:00 — 7 commitsWed 18:00 — 3 commitsWed 19:00 — 0 commitsWed 20:00 — 1 commitsWed 21:00 — 3 commitsWed 22:00 — 1 commitsWed 23:00 — 4 commitsThu 0:00 — 0 commitsThu 1:00 — 2 commitsThu 2:00 — 1 commitsThu 3:00 — 1 commitsThu 4:00 — 0 commitsThu 5:00 — 0 commitsThu 6:00 — 0 commitsThu 7:00 — 0 commitsThu 8:00 — 1 commitsThu 9:00 — 2 commitsThu 10:00 — 7 commitsThu 11:00 — 11 commitsThu 12:00 — 13 commitsThu 13:00 — 1 commitsThu 14:00 — 8 commitsThu 15:00 — 9 commitsThu 16:00 — 2 commitsThu 17:00 — 7 commitsThu 18:00 — 3 commitsThu 19:00 — 0 commitsThu 20:00 — 0 commitsThu 21:00 — 0 commitsThu 22:00 — 3 commitsThu 23:00 — 2 commitsFri 0:00 — 0 commitsFri 1:00 — 0 commitsFri 2:00 — 0 commitsFri 3:00 — 0 commitsFri 4:00 — 0 commitsFri 5:00 — 0 commitsFri 6:00 — 0 commitsFri 7:00 — 1 commitsFri 8:00 — 2 commitsFri 9:00 — 0 commitsFri 10:00 — 2 commitsFri 11:00 — 7 commitsFri 12:00 — 2 commitsFri 13:00 — 6 commitsFri 14:00 — 3 commitsFri 15:00 — 4 commitsFri 16:00 — 3 commitsFri 17:00 — 4 commitsFri 18:00 — 6 commitsFri 19:00 — 5 commitsFri 20:00 — 1 commitsFri 21:00 — 6 commitsFri 22:00 — 6 commitsFri 23:00 — 0 commitsSat 0:00 — 6 commitsSat 1:00 — 9 commitsSat 2:00 — 4 commitsSat 3:00 — 0 commitsSat 4:00 — 0 commitsSat 5:00 — 0 commitsSat 6:00 — 0 commitsSat 7:00 — 0 commitsSat 8:00 — 0 commitsSat 9:00 — 0 commitsSat 10:00 — 1 commitsSat 11:00 — 4 commitsSat 12:00 — 3 commitsSat 13:00 — 11 commitsSat 14:00 — 1 commitsSat 15:00 — 1 commitsSat 16:00 — 0 commitsSat 17:00 — 0 commitsSat 18:00 — 2 commitsSat 19:00 — 6 commitsSat 20:00 — 3 commitsSat 21:00 — 3 commitsSat 22:00 — 2 commitsSat 23:00 — 3 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.
DateListRankStars gained
Aug 7, 2026daily#9+1,190
Aug 6, 2026daily#5+1,582
Aug 5, 2026daily#3+2,540
Aug 4, 2026daily#2+1,699
  • freeCodeCamp/freeCodeCamp

    freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.

    453.6K stars · TypeScript

  • donnemartin/system-design-primer

    Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.

    362.2K stars · Python

  • practical-tutorials/project-based-learning

    Curated list of project-based tutorials

    277.1K stars · Python

  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    195K stars · Rust

  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    194.9K stars · Rust

  • ultraworkers/claw-code

    An agent-managed museum exhibit, built in Rust with Gajae-Code / LazyCodex — developed and maintained with no human intervention.

    194.9K stars · Rust