Skip to main content
Each persona shows pages a fixed list of font families for its platform and hides every other font on the host. The browser does not ship fonts. A family on the list shows up only if it is installed on the host, so installing the fonts is part of setting up a host.

What each persona shows

Every persona gets its platform’s core list. The Linux persona also has an optional list that the seed includes or leaves out. The same seed always gets the same lists. Font lists has every family of every list. The lists come from resources/profiles/dispersion/font_packs.json. The Windows lists have no Office fonts, because a few Office families without the rest of Office is a font list no real machine has. --fingerprint-explain names the lists a launch drew on its font_packs rows:

Other names on Windows

A Windows persona also answers the other names Windows answers to, with the family Windows uses for each: A name shows only when its family is on the list and installed, and none of them reaches a host font of that name. On a Mac host, only Courier, MS Sans Serif, MS Serif and Times work this way. Helvetica, Franklin Gothic and Arial Narrow stay hidden there.

Install the fonts

On a Linux or macOS host, run:
The command needs git. It does four things:
  1. It clones MauCariApa-com/windows-11-fonts into a temporary directory.
  2. From 0.4.4, it adds Marlett, which every Windows machine has and that repository lacks. It reads only marlett.ttf out of the liblaf/fonts Win11-English.zip with HTTP range requests, about 80 KB of a 200 MB zip, and keeps the file only if its SHA-256 matches the one the command pins. If the download fails, it prints why and installs the rest.
  3. It installs the files whose family is on the Windows list, and no others. A file counts by the family name Windows lists it under.
  4. It lists the families the host still lacks.
On a Mac it installed 143 files, Marlett included, and ended with every core Windows family is installed. The 0.4.3 command installs the same files without Marlett. When families are missing, it prints still missing and their names instead.Running the command again removes files in that directory that are not on the Windows list.To take the fonts from a real Windows machine instead, copy its C:\Windows\Fonts folder to the host and install from it. This takes every family on the list, Marlett included, from that folder:
Apostate does not ship these fonts. The repository and the zip have their own licences, and the command fetches them on your machine. The fonts are ordinary user fonts, so other programs on the host can use them.
A default launch on a Linux host is a Windows persona, so on a Linux server the Windows install is the one font step. Linux servers and Docker include it.

If fonts are missing

A page sees the families that are on the persona’s list and installed on the host. A missing family is absent, and nothing warns you. The browser does not fake a font it does not have. A Windows persona on a Linux host with no Windows fonts shows almost no fonts, which no real Windows machine does. Check the host after every new setup. The host’s font engine draws the glyphs, so even with the real Windows files, text metrics can differ slightly from Windows. Known gaps covers this. iphey.com flags every composed persona as inconsistent because of the font filter, the macOS persona on a Mac included. Known gaps has the measurements.

Check the fonts

On a Linux host, fc-list shows what is installed:
In the browser, queryLocalFonts() lists the families a page can see. It needs the local-fonts permission.
That output is from a Mac host with every Windows file installed. On a macOS host, families named after a weight, such as Segoe UI Light, Calibri Light and Yu Gothic Medium, do not list on their own, so a Windows persona lists 70 of its 90 families there (measured 2026-09-27, Apostate 0.4.3, macOS arm64 host). Compare the count and names with Font lists. document.fonts.check() cannot answer this. It returns true for any family name that no web font on the page uses, including names that do not exist. To test one family without the permission, compare text widths against the generic fallbacks:
Passed to page.evaluate() with ["Segoe UI", "Menlo", "NoSuchFont"] under a Windows persona, it returns {'Segoe UI': True, 'Menlo': False, 'NoSuchFont': False}. Menlo is installed on the Mac host, and the persona hides it.