A browser-only font fingerprinting demo. Guesses who you are from the fonts your installed software has left behind.
Open a real tracker's DevTools and you might never see what it's doing. Open this one and every line is right there. Same technique, no destination.
Every program you install drops fonts onto your system. Microsoft Office leaves Calibri. Adobe Creative Cloud leaves Myriad Pro and a long tail of pro faces. JetBrains IDEs leave JetBrains Mono. Mathematica leaves its own glyphs.
The page probes for roughly sixty of these fonts, tags each hit by the kind of software it ships with (developer, designer, office, academic, and so on), and tells you which group you look most like.
Nothing leaves your browser. That is the entire point.
A toggle at the top of the page lets you flip between the two techniques and re-run the scan.
Constructs an @font-face whose only source is local("FontName"). The browser's font engine resolves the local face, or fails. The CSS rule itself is the comparison.
@font-face {
font-family: "__probe__";
src: local("Calibri");
}If Calibri is on the machine, the face loads. If not, the load rejects.
Renders a probe string in three fallback families (monospace, sans-serif, serif) on an HTML canvas, then re-renders with the candidate font prepended. A width difference means the font resolved.
The classic technique from Fifield & Egelman, 2015. Slightly less elegant than the CSS version, slightly more compatible across browsers.
Open DevTools, then the Network tab. You will see only static assets load (HTML, CSS, JS, JSON, woff2 fonts), all from the same origin. No Google Fonts call. No analytics. No cookies. No telemetry.
Browsers with strict anti-fingerprinting protections (Tor, Brave on maximum shields, Safari with advanced tracking protection) return uniform measurements and report no signal. That is what those protections are for, and the demo is happy to show it.
Any static server works. Python's built-in is enough:
python3 -m http.server 8765Then open http://localhost:8765/
The page uses ES modules, so it must be served over HTTP. It will not work by double-clicking index.html from disk.
Static site, zero build step. Push to GitHub Pages, Netlify, Vercel, Cloudflare Pages, or any object store with HTTP. Drop the whole folder in and it works.
index.html masthead, hero, scan UI, verdict, specimen list
styles.css editorial type-specimen styling, self-hosted @font-face block
js/detector.js the two font probing methods, CSS and JS
js/app.js scan orchestration, scoring, rendering
data/fonts.json ~60 fonts tagged by software profile
fonts/ self-hosted woff2 files for Fraunces, Newsreader, JetBrains Mono
hero.png repository banner
This is a proof of concept. The font database is small (about sixty hand-picked entries) and the profile categories are coarse. Real font fingerprinting in the wild probes hundreds to thousands of faces and combines the signal with other entropy sources (canvas, audio, WebGL, screen, user-agent). The goal here is legibility. Accuracy was never the point.
If the page reports the wrong group for you, the right answer is usually "your machine has a less-common font mix than this database is built to catch."
- Fifield & Egelman, 2015, Fingerprinting web users through font metrics
- BrowserLeaks, Font Fingerprinting
- Oliver Brotchie, CSS-Fingerprint (server-logged variant)
Code in this repository is released under the MIT License. See LICENSE.
The bundled webfonts (Fraunces, Newsreader, JetBrains Mono) are redistributed under the SIL Open Font License 1.1 granted by their respective authors.
This is a proof of concept and is not maintained as a library. Read the ideas, copy the code, fork the repo. No support.
