Why Contribute to Someone Else’s Project
geo-seo-claude is a GEO-first SEO skill for Claude Code built by Zubair Trabzada — citability scoring, AI crawler analysis, brand authority, schema markup, and PDF reports. 2,700+ stars and 445+ forks in about a month.
geo-seo-claude is not in our dependency stack the way grammY is — it is a tool we use, built and maintained by someone else. We were reading the codebase, spotted two things worth fixing, and submitted PRs. Both were merged by the repo owner four days later.
Open source works when people fix what they find, not just what they need. Contributing upstream to your own framework is maintenance. Improving a tool you use but did not build is participation.
PR #13 — Eliminating Redundant HTML Parses
The fetch_page() function in scripts/fetch_page.py was parsing the HTML response with BeautifulSoup(response.text, "lxml") once at the top, then re-parsing the exact same HTML three more times later in the function. One parse for JSON-LD structured data extraction. Two more for SSR detection.
The reason for the redundant parses was subtle. The original soup object gets destructively modified — decompose() strips out script, style, and nav elements to isolate text content. That destroys the <script type="application/ld+json"> tags needed for structured data extraction, so the code re-parsed the HTML from scratch to get a clean copy.
The fix: reorder the operations. Move JSON-LD extraction and SSR detection before the destructive decompose() calls. They can safely reuse the existing soup object because they don’t depend on the stripped elements. Text content extraction still comes after decompose(), unaffected.
# Before: parse → decompose → re-parse (×3) → extract
# After: parse → extract JSON-LD → detect SSR → decompose → extract text
# JSON-LD and SSR detection moved above decompose()
# so they reuse the original soup object.
# 3 redundant lxml parses eliminated.
A reorder, not a rewrite. No behavioral change — +15/−17 lines in a single file. The same data gets extracted in the same way, just without parsing the same HTML four times. On large pages, that is a meaningful performance difference. lxml parsing is not free.
PR #14 — Standardizing Import Error Messages
All five Python scripts in scripts/ have ImportError handlers that print install instructions when a required package is missing. The messages were inconsistent: four scripts told users to run pip install requests beautifulsoup4, while the fifth (generate_pdf_report.py) said pip install reportlab. Each script listed only its own immediate dependencies.
The project already has a requirements.txt with all dependencies pinned. Telling users to install individual packages one at a time is both incomplete and fragile — it misses transitive dependencies and version constraints.
The fix: standardize all five error messages to point at the single source of truth.
# Before (inconsistent across 5 files)
"pip install requests beautifulsoup4"
"pip install reportlab"
# After (all 5 files)
"ERROR: Required packages not installed. Run: pip install -r requirements.txt"
+5/−5 lines across five files. A one-line change per script, pointing at the single source of truth.
Small Fixes, Clean PRs
Both PRs are targeted improvements. One eliminates redundant work in a hot path. The other standardizes five error messages. Surgical, scoped, no behavioral changes. The kind of improvements you only find by actually reading the code — not skimming it, reading it.
That is what GlacierPhonk brings to open source. Reading the code, understanding the architecture, and submitting changes that make the project better without making it different.
2 PRs merged into geo-seo-claude.