fontfetch 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -0
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/dist/cli.js +927 -0
- package/dist/cli.js.map +1 -0
- package/package.json +70 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to fontfetch will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.6.0] — 2026-05-27
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Provenance grouping.** Every downloaded font now lives under `files/<bucket>/<name>`, where bucket is one of `google` / `adobe-typekit` / `commercial` / `open-cdn` / `self-hosted`. Same first-match-wins precedence as the license heuristic; same-origin URLs (with `www.` and subdomain handling) fall to `self-hosted`.
|
|
13
|
+
- New module `src/provenance.ts` with `bucketForUrl(url, pageHost)` and `sameOrigin(a, b)` helpers.
|
|
14
|
+
- 18 unit tests for bucketing and same-origin detection.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Breaking layout change** (no published consumers): font files moved from `files/*.woff2` to `files/<bucket>/*.woff2`. `fonts.css`, `fonts.json`, `LICENSE_REVIEW.md`, and every framework emitter now reference the bucketed paths automatically.
|
|
18
|
+
- Per-file progress log prefixes the bucket: `✓ google/Inter-Regular.woff2` instead of `✓ Inter-Regular.woff2`.
|
|
19
|
+
|
|
20
|
+
### Notes
|
|
21
|
+
- v0.5 was originally scoped as a static `preview.html`. We've decided to skip that and roll it into a much larger v0.5 — a hosted Next.js webapp at `fontfetch.dev` with live progress, foundry-style previews, side-by-side compare, and font-pairing. See [docs/roadmap.md](docs/roadmap.md#v05--hosted-webapp) for the public plan.
|
|
22
|
+
|
|
23
|
+
## [0.4.0] — 2026-05-27
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **License heuristic + `LICENSE_REVIEW.md`**. Every pull now classifies each face as `open`, `commercial`, or `unknown` based on a URL-signature heuristic (Adobe Typekit, Monotype `fast.fonts.net`, Hoefler `cloud.typography.com`, Type Network, Adobe Fonts) plus a family-name fallback against a curated SIL OFL / Google Fonts catalog snapshot. Result is written as `LICENSE_REVIEW.md` alongside the rest of the per-site bundle.
|
|
27
|
+
- **Fail-fast on all-commercial sites.** When every detected face is served from a known commercial-foundry CDN, fontfetch aborts before downloading. It still emits `LICENSE_REVIEW.md` so the user can see what was detected, and prints a clear message recommending `--force` if they have a legitimate reason to proceed.
|
|
28
|
+
- **`--force` flag.** Bypasses the fail-fast check. Mirrors `npm install --force` semantics — you're telling the tool "I know what I'm doing."
|
|
29
|
+
- 12 new unit tests for the classifier and summarizer (`test/license.test.ts`).
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- CLI summary line at the end of a successful run now shows the license breakdown (`open / commercial / unknown` counts).
|
|
33
|
+
|
|
34
|
+
### Notes
|
|
35
|
+
- The classifier is heuristic-only and conservative on purpose — false-commercial is a safer failure mode than false-open (which could mislead a user into shipping a paid font).
|
|
36
|
+
- Adding a CDN signature is a one-line change in [src/license-data.ts](src/license-data.ts). PRs welcome.
|
|
37
|
+
|
|
38
|
+
## [0.3.0] — 2026-05-27
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- **`--emit <targets>` flag**. Comma-separated framework targets emitted alongside the default `fonts.css`:
|
|
42
|
+
- `next` → `next.fonts.ts` using `next/font/local`, one `localFont` call per family with all weights/styles, plus a CSS variable per family ready to spread into `<html>`
|
|
43
|
+
- `tailwind` → `tailwind.fonts.ts` with `fontFamily` mapped into `sans` / `serif` / `mono` (heuristic) plus per-family aliases. Pairs with `--emit next` for CSS variables
|
|
44
|
+
- `vite` → `vite.fonts.md` with a copy-paste integration guide
|
|
45
|
+
- `css` → default (no-op flag; just makes the default explicit)
|
|
46
|
+
- Multiple targets allowed: `--emit next,tailwind` emits both
|
|
47
|
+
- `--emit=next,tailwind` (equals form) also accepted
|
|
48
|
+
- New `src/emitters/` module with one file per target, a shared `util.ts`, and a typed `Emitter` interface
|
|
49
|
+
- Vitest test harness with unit tests for every emitter and the utility helpers
|
|
50
|
+
- CI now runs `npm run test` between typecheck and build
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- `tsconfig.json` now includes `test/**/*` so the test files are typechecked alongside source
|
|
54
|
+
- Bumped to v0.3.0
|
|
55
|
+
|
|
56
|
+
## [0.2.2] — 2026-05-27
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
- **Referer-aware font downloads.** Every font request now sends a `Referer` header set to the originating page URL (the same header browsers send automatically when loading subresources). Many foundry CDNs and some self-hosted setups return 403 without it. Mirrors what we already do for stylesheet fetches.
|
|
60
|
+
- `fetchBuffer` in [src/utils.ts](src/utils.ts) now accepts an optional `headers` parameter, parallel to `fetchText`.
|
|
61
|
+
|
|
62
|
+
### Notes
|
|
63
|
+
- Out of scope: bypassing signed-URL or session-bound foundry protection. That's a v0.4 concern (fail-fast on known commercial CDNs).
|
|
64
|
+
|
|
65
|
+
## [0.2.1] — 2026-05-27
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
- **Orphan-file auto-download.** In `--headless` mode, font URLs observed in the browser's network log that aren't referenced by any parsed `@font-face` rule (typically from cross-origin stylesheets) are now downloaded automatically into `files/` and listed under a new `orphan_files` array in `fonts.json`.
|
|
69
|
+
- Per-site `README.md` now includes an "Orphan files" section explaining what they are and how to wire them up manually.
|
|
70
|
+
|
|
71
|
+
### Changed
|
|
72
|
+
- **`fonts.json` shape**: previously a top-level `FontFace[]` array; now an object `{ faces: FontFace[], orphan_files: { file, url }[] }`. Pre-1.0 — no existing consumers — so no migration path was provided.
|
|
73
|
+
|
|
74
|
+
## [0.2.0] — 2026-05-27
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- **`--headless` flag** — Playwright/Chromium mode that catches JS-loaded fonts, late-injected `@font-face` rules, and SPA-rendered content. Merges results with the static parser; dedupes faces across both sources.
|
|
78
|
+
- New `src/headless.ts` module with dynamic import of Playwright (graceful fail if not installed).
|
|
79
|
+
- Network-response listener that also observes font URLs at the browser level (logged in v0.2; auto-downloaded in v0.2.1).
|
|
80
|
+
- Playwright is wired as an **optional peer dependency** — the static path stays zero-runtime-deps.
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
- CLI help text and README document the new `--headless` flag and install steps.
|
|
84
|
+
- Bumped to v0.2.0.
|
|
85
|
+
|
|
86
|
+
### Notes
|
|
87
|
+
- Headless mode requires `npm install playwright` + `npx playwright install chromium` once per machine.
|
|
88
|
+
- Static mode is unchanged and still the default.
|
|
89
|
+
|
|
90
|
+
## [0.1.1] — 2026-05-27
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
- **Community font-pairing registry** at `pairings/` — JSON files describing fonts used by real websites, with free OFL alternatives for commercial fonts
|
|
94
|
+
- JSON Schema (`pairings/_schema.json`) with validation rules
|
|
95
|
+
- Issue template (`.github/ISSUE_TEMPLATE/font_pairing.yml`) for non-technical contributors — fill a form, drag a screenshot
|
|
96
|
+
- AI-agent prompt in `pairings/README.md` so anyone can use Claude/ChatGPT/Cursor to draft a pairing JSON
|
|
97
|
+
- CI workflow (`.github/workflows/validate-pairings.yml`) that validates new pairings against the schema on every PR
|
|
98
|
+
- Seed pairings: Stripe, Linear, Vercel
|
|
99
|
+
- Pairings data released under CC0 — public domain, reusable by any third-party tool
|
|
100
|
+
|
|
101
|
+
### Notes
|
|
102
|
+
- The CLI itself is unchanged in v0.1.1. This release ships repo infrastructure for the community registry.
|
|
103
|
+
|
|
104
|
+
## [0.1.0] — 2026-05-27
|
|
105
|
+
|
|
106
|
+
### Added
|
|
107
|
+
- Initial release.
|
|
108
|
+
- CLI: `fontfetch <url> [outDir]`
|
|
109
|
+
- Static `@font-face` parser: linked stylesheets, inline `<style>`, `<link rel="preload" as="font">`
|
|
110
|
+
- Per-site output folder with `files/`, `fonts.css` (local URLs), `fonts.json` manifest, and a human-readable `README.md`
|
|
111
|
+
- Collision-safe filenames across CDNs
|
|
112
|
+
- Node 18+, pure ESM, zero runtime dependencies
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Niyam Vora
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# fontfetch
|
|
2
|
+
|
|
3
|
+
> Download every web font from any site into a project-ready folder — with CSS, manifest, and framework configs ready to drop in.
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://www.npmjs.com/package/fontfetch"><img src="https://img.shields.io/npm/v/fontfetch.svg?style=flat-square" alt="npm" /></a>
|
|
7
|
+
<a href="https://github.com/niyamvora/fontfetch/actions"><img src="https://img.shields.io/github/actions/workflow/status/niyamvora/fontfetch/ci.yml?branch=main&style=flat-square" alt="ci" /></a>
|
|
8
|
+
<img src="https://img.shields.io/badge/license-MIT-black?style=flat-square" alt="MIT" />
|
|
9
|
+
<img src="https://img.shields.io/node/v/fontfetch?style=flat-square" alt="node" />
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx fontfetch https://stripe.com
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
→ Fetching page: https://stripe.com
|
|
18
|
+
3 external stylesheet(s), 0 inline <style> block(s)
|
|
19
|
+
→ Found 12 @font-face declaration(s), 18 unique file(s)
|
|
20
|
+
✓ SohneBreit-Buch.woff2 (32,180 bytes)
|
|
21
|
+
✓ Sohne-Buch.woff2 (28,044 bytes)
|
|
22
|
+
...
|
|
23
|
+
Done. 18/18 files saved to ./downloaded-fonts/stripe.com
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
That's it. Real font files, a ready-to-paste `fonts.css` with local URLs, a JSON manifest, and a README — all in one folder you can drag straight into `public/fonts/`.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Why this exists
|
|
31
|
+
|
|
32
|
+
You're mocking up a design. You see a font you like on a marketing site. You want to test it locally for a few hours of iteration — not ship it to production, just see how your design feels with that typography.
|
|
33
|
+
|
|
34
|
+
The existing options aren't great:
|
|
35
|
+
- **`google-webfonts-helper`** — beautiful, but Google Fonts only
|
|
36
|
+
- **`webfont-dl`** — works, but you have to find the CSS URL yourself
|
|
37
|
+
- **Chrome extensions** — point-and-click, no automation, no project integration
|
|
38
|
+
|
|
39
|
+
**fontfetch** takes a URL. Returns a folder. That's the whole product.
|
|
40
|
+
|
|
41
|
+
## What you get
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
downloaded-fonts/
|
|
45
|
+
└── stripe.com/
|
|
46
|
+
├── files/ ← raw woff2 / woff / ttf / otf
|
|
47
|
+
│ ├── Sohne-Buch.woff2
|
|
48
|
+
│ ├── Sohne-Halbfett.woff2
|
|
49
|
+
│ └── ...
|
|
50
|
+
├── fonts.css ← @font-face block with local URLs
|
|
51
|
+
├── fonts.json ← manifest: family / weight / style / files
|
|
52
|
+
└── README.md ← human-readable summary, grouped by family
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Drop the folder into `public/fonts/` (or wherever), link `fonts.css`, done.
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
Run on demand:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx fontfetch <url>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or install globally:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install -g fontfetch
|
|
69
|
+
fontfetch <url>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Requires Node 18+.
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
fontfetch <url> [outDir] [--headless]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Arg / Flag | Default | Notes |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `<url>` | — | Page to download fonts from (use the page where the font is actually rendered) |
|
|
83
|
+
| `[outDir]` | `./downloaded-fonts` | Per-site subfolder is created inside this |
|
|
84
|
+
| `--headless` | off | Launch Playwright/Chromium to also catch JS-loaded fonts |
|
|
85
|
+
|
|
86
|
+
Examples:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
fontfetch https://stripe.com
|
|
90
|
+
fontfetch https://linear.app ./public/fonts
|
|
91
|
+
fontfetch https://vercel.com /tmp/scratch
|
|
92
|
+
fontfetch https://some-spa.com --headless
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### License review (v0.4)
|
|
96
|
+
|
|
97
|
+
Every pull writes `LICENSE_REVIEW.md` alongside the rest of the per-site output. Each face is classified by a URL-signature heuristic (Adobe Typekit, Monotype, Hoefler, Type Network, etc.) plus a family-name fallback against a curated SIL OFL / Google Fonts catalog snapshot.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
→ License review: 8 open / 2 commercial / 3 unknown
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Fail-fast.** When every detected font is served from a known commercial-foundry CDN, fontfetch aborts before downloading and emits only `LICENSE_REVIEW.md`. Pass `--force` to download anyway (e.g. for a local mockup of a site whose fonts you've licensed).
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
fontfetch https://commercial-foundry-site.com # aborts, writes LICENSE_REVIEW.md
|
|
107
|
+
fontfetch https://commercial-foundry-site.com --force # downloads anyway
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Not legal advice. The classifier is heuristic-only and conservative on purpose — verify before shipping.
|
|
111
|
+
|
|
112
|
+
### Framework emitters (v0.3)
|
|
113
|
+
|
|
114
|
+
Pass `--emit <target,target,...>` to generate framework-ready config files alongside the default `fonts.css`.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
fontfetch https://vercel.com --emit next,tailwind
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Targets:
|
|
121
|
+
|
|
122
|
+
| Target | Emits | Use it for |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `next` | `next.fonts.ts` | Drop-in `next/font/local` config — one `localFont` call per family with all weights, plus a CSS variable |
|
|
125
|
+
| `tailwind` | `tailwind.fonts.ts` | `fontFamily` snippet for `tailwind.config.ts` — `sans` / `serif` / `mono` heuristic + per-family aliases. Pairs with `next` for CSS variables |
|
|
126
|
+
| `vite` | `vite.fonts.md` | Copy-paste integration guide. Vite needs no plugin — the default `fonts.css` is already a drop-in stylesheet |
|
|
127
|
+
| `css` | (default) | Explicit no-op |
|
|
128
|
+
|
|
129
|
+
Output ends up alongside the rest of the per-site bundle:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
downloaded-fonts/vercel-com/
|
|
133
|
+
├── files/
|
|
134
|
+
├── fonts.css
|
|
135
|
+
├── fonts.json
|
|
136
|
+
├── README.md
|
|
137
|
+
├── next.fonts.ts ← --emit next
|
|
138
|
+
└── tailwind.fonts.ts ← --emit tailwind
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Headless mode (v0.2)
|
|
142
|
+
|
|
143
|
+
By default fontfetch is **static** — it fetches the HTML, reads every linked stylesheet and inline `<style>`, and parses `@font-face` rules. That covers ~90% of real-world sites and is fast.
|
|
144
|
+
|
|
145
|
+
For SPAs that load fonts at runtime, sites that inject `@font-face` blocks via JavaScript after hydration, or pages behind a Cloudflare challenge, pass `--headless`. fontfetch will launch a headless Chromium via Playwright, wait for `document.fonts.ready`, and dump every `@font-face` rule it can see — merged with the static results.
|
|
146
|
+
|
|
147
|
+
Install Playwright + Chromium once:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npm install playwright
|
|
151
|
+
npx playwright install chromium
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Then:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
fontfetch https://example.com --headless
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Playwright is an **optional peer dependency** — install it only if you need this mode. The static path runs with zero runtime dependencies.
|
|
161
|
+
|
|
162
|
+
## How it works
|
|
163
|
+
|
|
164
|
+
1. Fetches the page HTML
|
|
165
|
+
2. Pulls every `<link rel="stylesheet">` and inline `<style>` block
|
|
166
|
+
3. Parses every `@font-face` block: family, weight, style, unicode-range, src
|
|
167
|
+
4. Also grabs `<link rel="preload" as="font">` references
|
|
168
|
+
5. Downloads every unique font file
|
|
169
|
+
6. Rewrites the `@font-face` blocks with local `./files/...` URLs
|
|
170
|
+
7. Emits `fonts.css`, `fonts.json`, and a `README.md`
|
|
171
|
+
|
|
172
|
+
No browser launched, no dependencies pulled at install time outside of TypeScript build tooling. The whole CLI is one small ESM bundle.
|
|
173
|
+
|
|
174
|
+
## How it compares
|
|
175
|
+
|
|
176
|
+
| Tool | Any URL | JS-rendered fonts | Framework config emit |
|
|
177
|
+
|---|---|---|---|
|
|
178
|
+
| `google-webfonts-helper` | Google Fonts only | n/a | ✗ |
|
|
179
|
+
| `webfont-dl` | Needs CSS URL | ✗ | ✗ |
|
|
180
|
+
| Chrome extensions | ✓ (manual) | ✓ | ✗ |
|
|
181
|
+
| **`fontfetch`** | ✓ | _v0.2_ | _v0.3_ |
|
|
182
|
+
|
|
183
|
+
## Roadmap
|
|
184
|
+
|
|
185
|
+
- [x] **v0.1** — Static `@font-face` extraction, ready-to-use CSS, manifest, README
|
|
186
|
+
- [x] **v0.1.1** — [Community font-pairing registry](./docs/roadmap.md#v011--community-font-pairing-registry): share what fonts your favorite sites use, with free OFL alternatives
|
|
187
|
+
- [x] **v0.2** — `--headless` flag: Playwright mode for JS-loaded fonts (Adobe Typekit, SPAs, Cloudflare-protected sites)
|
|
188
|
+
- [x] **v0.2.2** — Referer-aware font downloads (unblocks foundry CDNs that 403 without a Referer)
|
|
189
|
+
- [x] **v0.3** — Framework emitters: `--emit next` / `tailwind` / `vite`
|
|
190
|
+
- [x] **v0.4** — License heuristic + `LICENSE_REVIEW.md` + fail-fast on all-commercial sites (`--force` to bypass)
|
|
191
|
+
- [ ] **v0.5** — [Hosted webapp at `fontfetch.dev`](./docs/roadmap.md#v05--hosted-webapp): URL → live progress → foundry-style previews → compare + pairing
|
|
192
|
+
- [x] **v0.6** — Provenance grouping: output split into `google/` / `adobe-typekit/` / `commercial/` / `open-cdn/` / `self-hosted/`
|
|
193
|
+
- [ ] **v0.4** — License heuristic: flag Google Fonts vs commercial foundries in `LICENSE_REVIEW.md`
|
|
194
|
+
- [ ] **v0.5** — Visual preview gallery: auto-generate `preview.html` with pangrams per family × weight × style
|
|
195
|
+
- [ ] **v0.6** — Provenance grouping: split output into `google/`, `adobe-typekit/`, `self-hosted/`, `cdn/`
|
|
196
|
+
|
|
197
|
+
Want one of these sooner? Open an issue or vote on existing ones.
|
|
198
|
+
|
|
199
|
+
## Responsible use
|
|
200
|
+
|
|
201
|
+
Font files are software, licensed under EULAs. **fontfetch is intended for local design exploration and testing, not for shipping paid fonts you haven't licensed.** Using a font for a few hours of mockup work in a private project is different from bundling it into a production app. We don't gate the tool — we trust you to know the difference and respect foundry licenses.
|
|
202
|
+
|
|
203
|
+
For production use, the [Google Fonts](https://fonts.google.com) catalog and the [SIL Open Font License](https://openfontlicense.org/) library are designed to be self-hosted freely. Every entry in our [pairings registry](./pairings) lists free alternatives for paid fonts.
|
|
204
|
+
|
|
205
|
+
## Font pairings registry
|
|
206
|
+
|
|
207
|
+
[`pairings/`](./pairings) is a community-curated list of fonts used by real websites — with **free OFL alternatives** for every commercial font.
|
|
208
|
+
|
|
209
|
+
[**→ Submit a pairing**](https://github.com/niyamvora/fontfetch/issues/new?template=font_pairing.yml) (fill a form, drag a screenshot, done — or [ask an AI to do it for you](./pairings#b-ask-an-ai-to-do-it-for-you)).
|
|
210
|
+
|
|
211
|
+
## Contributing
|
|
212
|
+
|
|
213
|
+
Issues and PRs welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the dev loop. The codebase is small and approachable — `src/` is a handful of files, no monorepo, no build magic, just `tsup`.
|
|
214
|
+
|
|
215
|
+
Good first issues are tagged `good first issue` on GitHub.
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
[MIT](./LICENSE) — © Niyam Vora
|