Save Ink, Save the planet.
Ecofonts is a 100% client-side font optimizer. It punches a grid of microscopic vector holes ("eco holes") into the interior of every glyph so your documents print with less ink β up to 20% less β while staying crisp and legible at reading sizes. Everything runs in your browser: no uploads, no servers, no accounts. Your files never leave your machine.
Upload any of the following and download the optimized result with the same name and structure:
| Input | What happens |
|---|---|
.ttf / .otf / .woff / .woff2 |
The font's glyphs get eco holes and the font is re-compiled; web fonts come back in the container they arrived in. |
.zip |
Every font inside is optimized (nested folders like Google Fonts' static/ included); other files pass through untouched. |
.pdf |
Every embedded font β TrueType, CFF/OpenType, and legacy Type 1 β is rewritten in place; layout and selectable text stay identical. |
An Eco Intensity slider (1β20%) controls how much ink is removed, and it's honest: the value maps to the measured share of glyph area actually subtracted. A minimum "wall" of ink is always preserved around every hole, so letter silhouettes are never notched and thin strokes keep their edges.
Requires Node.js β₯ 22.12.
npm install
npm run dev # dev server at http://localhost:4321
npm run build # production build to ./dist/
npm run preview # preview the production buildRoutes:
/β landing page with a drag-and-drop zone (drops are handed to the optimizer via IndexedDB and preselected there β pick an Eco Intensity and click Optimize)./fontβ the optimizer itself.
- Parse β glyph outlines are read with opentype.js (or, for PDF-embedded fonts, directly from the font binary by format-specific parsers).
- Flatten β BΓ©zier curves are subdivided into polygons in integer font units.
- Subtract β a globally aligned, staggered grid of octagonal holes is clipped against an inset of the glyph interior and subtracted with boolean geometry (clipper-lib). The inset guarantees a minimum wall thickness so outlines stay intact.
- Re-compile β new outlines are written back into a working font binary; ZIP archives are rebuilt with JSZip and PDFs with pdf-lib, preserving structure exactly.
For PDFs, purpose-built binary "surgeons" rewrite only the outline data and
keep every other byte of the font β glyph IDs, widths, encodings, and hinting
of untouched glyphs β exactly as the document expects, which is what makes
subset fonts without cmap/name tables work:
src/lib/glyf.ts patches the glyf/loca tables of
TrueType fonts, src/lib/cff.ts re-emits the Type 2
charstrings of CFF/OpenType fonts, and src/lib/type1.ts
splices new charstrings into decrypted legacy Type 1 fonts.
- Astro (static output) + React
via
@astrojs/reactfor the optimizer UI opentype.jsΒ·clipper-libΒ·jszipΒ·pdf-libΒ·woff2-encoderβ all loaded on demand, so the initial page stays light- No backend of any kind β the site deploys as plain static files
- Re-compiled fonts are CFF-flavored OpenType inside (an opentype.js
constraint); they install and render everywhere and keep their original
name and container (
.woff/.woff2uploads are re-wrapped after processing). - Ligatures (GSUB) and variation axes are dropped from re-compiled fonts; variable fonts come back as their default instance (upload the family ZIP to keep all weights).
- In PDFs, all embedded font formats are rewritten β TrueType (
FontFile2), CFF/OpenType (FontFile3), and legacy Type 1 (FontFile). Only text drawn with non-embedded viewer fonts cannot be optimized. - Optimized files are larger than the originals (curves become line segments); that's inherent to the approach.
Ecofonts modifies fonts locally and never redistributes anything, but whether you may modify a given font depends on its license. Open licenses such as the SIL Open Font License explicitly allow modification; for commercial fonts, check your license terms.
See CONTRIBUTING.md.