majodev/google-webfonts-helper
A Hassle-Free Way to Self-Host Google Fonts. Get eot, ttf, svg, woff and woff2 files + CSS snippets
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2mo ago
- ✓8 active contributors
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Single-maintainer risk — top contributor 93% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/majodev/google-webfonts-helper)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/majodev/google-webfonts-helper on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: majodev/google-webfonts-helper
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/majodev/google-webfonts-helper shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across all four use cases
- Last commit 2mo ago
- 8 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Single-maintainer risk — top contributor 93% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live majodev/google-webfonts-helper
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/majodev/google-webfonts-helper.
What it runs against: a local clone of majodev/google-webfonts-helper — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in majodev/google-webfonts-helper | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 97 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of majodev/google-webfonts-helper. If you don't
# have one yet, run these first:
#
# git clone https://github.com/majodev/google-webfonts-helper.git
# cd google-webfonts-helper
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of majodev/google-webfonts-helper and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "majodev/google-webfonts-helper(\\.git)?\\b" \\
&& ok "origin remote is majodev/google-webfonts-helper" \\
|| miss "origin remote is not majodev/google-webfonts-helper (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 97 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~67d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/majodev/google-webfonts-helper"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
google-webfonts-helper is a web application that downloads Google Fonts and self-hosts them as optimized font files (eot, ttf, svg, woff, woff2) with auto-generated CSS snippets. It solves the need to avoid third-party CDN dependencies and GDPR/privacy concerns by letting developers host fonts on their own infrastructure while retaining browser compatibility. Client-server monorepo: client/ contains an AngularJS frontend (fonts controller, cssCode directive, UI components in Less) with Grunt-based build system. server/ contains Express.js TypeScript backend with API controllers (fonts.controller.ts, healthy.controller.ts) and business logic layer (server/logic/core.ts, fetchCSS.ts) that handles font downloading and CSS generation. Docker setup for containerized deployment.
Who it's for
Frontend developers and web designers who need to self-host Google Fonts without relying on Google's CDN; DevOps teams managing compliance-heavy projects requiring local font hosting; developers building static site generators or JAMstack projects that need font assets bundled locally.
Maturity & risk
Production-ready and actively maintained. The service runs at https://gwfh.mranftl.com with public uptime monitoring, has a TypeScript/Node.js backend with test coverage (spec files present in server/api/), GitHub Actions CI/CD pipelines (build-publish-deploy.yml), and Docker support. Regular updates visible in dependency versions (Express 4.21.2, Axios 1.12.2).
Low-to-moderate risk. Single maintainer (majodev) creates sustainability concerns despite sponsorship setup. Moderate dependency count (~20 core deps) but well-maintained choices (lodash, express, axios are stable). The app depends on Google Fonts API availability and CSS parsing accuracy, which could break if Google changes their font metadata format. No visible major security advisories in the dependency list.
Active areas of work
Active development with GitHub Actions workflows for build and deployment (build-publish-deploy.yml, docker.env). Recent TypeScript and dependency updates suggest ongoing maintenance. The repo tracks uptime and has sponsor integrations, indicating sustained effort. No specific milestone data visible, but the project is clearly supported.
Get running
git clone https://github.com/majodev/google-webfonts-helper.git
cd google-webfonts-helper
npm install
npm run dev
The project uses npm (package.json present), Grunt for task automation (Gruntfile.js), and Docker Compose for containerized setup (docker-compose.yml).
Daily commands:
npm run dev
For production: npm run build && npm start. Docker alternative: docker-compose up. Dev mode uses Grunt with livereload (connect-livereload ~0.4.0) and watches for changes.
Map of the codebase
- server/logic/core.ts: Core business logic for font processing, variant selection, and file optimization—the heart of the download pipeline
- server/logic/fetchCSS.ts: Handles fetching and parsing Google Fonts CSS, then generating self-hosted CSS snippets with correct @font-face rules
- server/api/fonts.controller.ts: Express route handler that exposes the font download and CSS generation as HTTP endpoints
- client/app/fonts/fonts.controller.js: AngularJS controller managing font selection UI state, model binding, and API communication
- Gruntfile.js: Build automation configuration for client asset pipeline (minification, concatenation, Less compilation, HTML templates)
- docker-compose.yml: Orchestrates containerized deployment with service definitions for consistent production/development environments
How to make changes
Adding font formats: modify server/logic/core.ts (core font processing logic). Changing CSS generation: edit server/logic/fetchCSS.ts. Frontend features: add controllers in client/app/[feature]/[feature].controller.js and directives in client/app/[feature]/[feature].directive.js. API endpoints: add new controller in server/api/ with corresponding spec file. Styling: edit client/app/app.less or component-specific .less files. Tests: follow spec.ts/spec.js pattern (server uses Mocha via grunt-mocha-test).
Traps & gotchas
No explicit env vars documented in file list—check .env files or docker.env for Google Fonts API endpoint configuration. Bower.json present—legacy package manager still used alongside npm; ensure bower install runs in Grunt pipeline. CSS parsing fragility: fetchCSS.ts parses Google's CSS format; if Google changes font metadata format or CSS structure, font variant detection breaks. AngularJS EOL: frontend uses AngularJS 1.x (not modern Angular), which is no longer maintained—refactoring to Vue/React would be a breaking change. File-type dependency: package.json includes file-type 16.5.4 for MIME detection; verify it supports all font formats (eot/ttf/svg/woff/woff2) your pipeline generates.
Concepts to learn
- CSS Parsing and AST Transformation — fetchCSS.ts parses Google's @font-face CSS rules into an AST, extracts font metadata (weights, styles, unicodes), and regenerates CSS for self-hosted paths—understanding CSS ASTs is critical to debugging font variant detection failures
- Web Font Format Conversion (eot/ttf/svg/woff/woff2) — The core value proposition is delivering multiple font formats for backward browser compatibility; understanding differences (compression, browser support timelines, file size tradeoffs) informs optimization decisions
- Express.js Middleware Pattern — server/app.ts chains middleware (compression, morgan logging, error handling) in a specific order; modifying request/response flow requires understanding how Express pipelines work
- AngularJS Dependency Injection — client/app/ uses AngularJS 1.x DI pattern (inject service names as function parameters); adding new services or modifying controllers requires understanding implicit string-based DI and ng-annotate compilation
- ZIP Archive Generation (jszip) — The app packages multiple font files into downloadable ZIP archives (jszip 3.10.1); understanding async file streaming and ZIP entry ordering matters for reliable bulk font downloads
- Grunt Build Automation & Task Chaining — Gruntfile.js chains 20+ grunt plugins in a specific order (asset injection, Less compilation, uglification); modifying the build pipeline requires understanding task dependencies and registerTask ordering
- GDPR/Privacy Self-Hosting Rationale — Users choose google-webfonts-helper specifically to avoid sending font requests to Google's CDN (IP tracking, request logging); understanding GDPR compliance drivers explains feature priorities and architectural constraints
Related repos
google/fonts— Official Google Fonts repository; primary upstream source for font metadata and file availability that google-webfonts-helper consumesfonttools/fonttools— Python library for font file manipulation and optimization; used by many font self-hosting tools for subsetting and format conversiontypeorm/typeorm— Not directly related, but projects that fork google-webfonts-helper to add database persistence for caching font metadata use TypeORM
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for server/logic/core.ts and server/logic/fetchGoogleFonts.ts
The core business logic for fetching and processing Google Fonts lacks comprehensive test coverage. Looking at the repo structure, server/logic/ contains critical functions (fetchCSS.ts, fetchFontSubsetArchive.ts, fetchFontURLs.ts, fetchGoogleFonts.ts, store.ts) but only core.ts has a corresponding .spec.ts file in the partial structure shown. The main entry point logic needs robust tests to prevent regressions when updating font processing or caching logic.
- [ ] Create server/logic/fetchGoogleFonts.spec.ts with tests for Google Fonts API integration
- [ ] Create server/logic/fetchFontURLs.spec.ts with tests for URL extraction and validation
- [ ] Create server/logic/fetchCSS.spec.ts with tests for CSS parsing and generation (uses 'css' dependency)
- [ ] Add tests for error handling in asyncRetry.ts integration with these fetch functions
- [ ] Ensure mocking of axios calls to avoid external API dependencies in tests
Add GitHub Actions workflow for automated dependency security scanning and updates
The repo has build-only.yml and build-publish-deploy.yml workflows but lacks automated dependency vulnerability scanning and Dependabot configuration. With 30+ direct dependencies including critical ones like express, axios, and jszip, automated security scanning would catch vulnerabilities early. A .github/dependabot.yml file and a security scanning workflow would significantly improve maintenance burden.
- [ ] Create .github/dependabot.yml to enable automated dependency updates for npm packages
- [ ] Create .github/workflows/security-scan.yml using npm audit or Snyk to scan for vulnerabilities
- [ ] Configure workflow to run on schedule (weekly) and on push to main branch
- [ ] Add configuration to automatically create PRs for security patches with appropriate labels
- [ ] Document the security scanning process in README.md under a 'Security' or 'Contributing' section
Add integration tests for client-server communication in client/app/fonts/
The client-side code (client/app/fonts/fonts.controller.js, client/app/fonts/fonts.controller.spec.js) exists but the .spec.js file is incomplete based on the structure. Given that fonts.js likely defines routing and fonts.controller.js handles font selection/download logic, end-to-end tests validating the full flow from client request through server API response are missing. This is critical for the core UX of selecting fonts and downloading archives.
- [ ] Review existing client/app/fonts/fonts.controller.spec.js and expand test coverage for font selection, filtering, and preview functionality
- [ ] Create integration tests that mock server/api/fonts.controller.ts responses and verify correct client-side rendering
- [ ] Add tests for the CSS snippet generation workflow through cssCode/cssCode.directive.spec.js and fonts controller interaction
- [ ] Add tests to validate correct archive download triggering through fetchFontSubsetArchive.ts via the fonts controller
- [ ] Use supertest or similar to mock HTTP responses and validate client state updates
Good first issues
- Add missing tests for server/logic/fetchCSS.ts: fetchCSS.ts has no spec file (fetchCSS.spec.ts is missing). Add tests covering: CSS parsing for different Google Fonts API responses, @font-face generation for each font format, edge cases like missing variant metadata.
- Document environment variables for Google Fonts API: README lacks explicit documentation of required env vars (Google Fonts API endpoint, API key if needed, rate limits). Add an .env.example file and update README with setup instructions for self-hosted deployments.
- Add TypeScript types for CSS parsing in core.ts: server/logic/core.ts uses the css library; add explicit TypeScript interfaces for parsed CSS objects (fonts, variants, weights) to improve maintainability and catch type errors early in the font processing pipeline.
Top contributors
- @majodev — 93 commits
- @Rotzbua — 1 commits
- @tomayac — 1 commits
- @mk360 — 1 commits
- @michaelmior — 1 commits
Recent commits
6043c3c— node@v22.20.0 on debian trixie, axios@v1.12.2, compression@v1.8.1, express@v4.21.2, morgan@v1.10.1 (majodev)43d11e4— fix ci pipeline (majodev)9ee5682— fix ci (majodev)f54aa7c— v1.7.0 prerelease, upgrades to node:v22, adds arm64 support (majodev)0fddfb8— fix #185 eot files missing (majodev)3b2747c— upgrades to node@20.13.1-bookworm, express@4.19.2, axios@1.6.8 (majodev)d167026— wire disable exclude bootstrap (majodev)31b3302— fix a multi items, add sponsor tooltip (majodev)66554d2— testdrive sponsors visible in navbar (majodev)50644e5— show sponsors in readme (majodev)
Security observations
- High · Outdated Compression Middleware —
package.json - dependencies. The 'compression' package version 1.8.1 is severely outdated (released in 2016). This version may contain known security vulnerabilities and lacks modern security patches. Fix: Update compression to the latest version (^1.7.4 or higher). Run 'npm audit' to identify known vulnerabilities. - High · Outdated Morgan Logging Middleware —
package.json - dependencies. Morgan version 1.10.1 is outdated and may contain security issues. Current versions are significantly newer. Fix: Update morgan to the latest stable version (^1.10.0 or higher). - High · Unvalidated External API Integration —
server/logic/fetchGoogleFonts.ts, server/logic/fetchCSS.ts, server/logic/fetchFontURLs.ts. The application uses axios to fetch Google Fonts and related resources (fetchGoogleFonts.ts, fetchCSS.ts, fetchFontURLs.ts). No visible input validation, rate limiting, or timeout mechanisms in the file structure. This could lead to SSRF, DoS, or malicious payload injection. Fix: Implement strict input validation, URL whitelisting, request timeouts, rate limiting, and response size limits. Validate all external API responses before processing. - High · Potential CSS Injection via CSS Parsing —
server/logic/fetchCSS.ts, package.json - css dependency. The application parses CSS from external sources (css version 3.0.0) without visible sanitization. The 'css' package version 3.0.0 is outdated and could be vulnerable to CSS injection attacks if user-controlled input reaches the CSS parser. Fix: Update css package to latest version. Implement strict CSS validation and sanitization. Use a robust CSS sanitizer library. Never directly render untrusted CSS. - Medium · Missing Content Security Policy Headers —
server/app.ts, server/routes.ts. No evidence of CSP, X-Frame-Options, X-Content-Type-Options, or other security headers in the codebase. The application serves web content but lacks basic security headers. Fix: Implement security headers middleware (e.g., helmet.js). Add CSP, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, and other headers. - Medium · Exposed Debug/Development Ports —
docker-compose.yml. Docker-compose.yml exposes multiple development ports (5858 debugger, 9229 profiler) that should never be exposed in production. These ports provide direct access to Node.js debugger and profiler. Fix: Remove debug ports from production configurations. Use separate docker-compose files for development and production. Implement proper secret management and never expose debug ports publicly. - Medium · Bluebird Promise Library Version —
package.json - dependencies. Bluebird 3.7.2 is outdated. While generally stable, newer Node.js versions have built-in Promise support, making this dependency potentially unnecessary and introducing maintenance debt. Fix: Consider removing bluebird dependency and using native Node.js Promises. If kept, update to the latest version. - Medium · Lodash Utility Library Risk —
package.json - dependencies. Lodash 4.17.21 is an older version. While not severely vulnerable, the package is widely used and newer versions should be considered. Some lodash functions can be exploited if used with untrusted data. Fix: Update lodash to the latest version. Review code usage of lodash functions for potential prototype pollution or other attacks when processing untrusted data. - Medium · Axios HTTP Client Without Request Signing/Validation —
server/logic/fetchGoogleFonts.ts, package.json - axios. Axios 1.12.2 is used for external API calls to Google Fonts API. No visible request signing, certificate pinning, or response validation in the file structure. Fix: Implement request signing if supported by Google Fonts API. Add certificate pinning for
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.