JavaScript Font Access API: Enumerate System Fonts
The Font Access API is a web platform feature that allows web applications to discover and access the full catalog of fonts installed locally on a user’s operating system. This article explains what the Font Access API is, the limitations it overcomes, how to use JavaScript to enumerate system fonts and access their metadata, and the key security and privacy safeguards built into the specification.
What is the Font Access API?
Historically, web browsers restricted direct access to local system fonts for privacy and security reasons. Web design and layout tools running in the browser could only display a predefined set of web fonts or rely on indirect CSS fallback techniques to guess whether a specific font was installed.
The Font Access API solves this limitation by providing a standardized, permission-gated interface. It gives advanced web applications—such as graphic design editors, word processors, and document viewers—the ability to provide a native-like font selection interface and access low-level font data directly from the user’s device.
How to Enumerate Local Fonts in JavaScript
The primary method for enumerating system fonts is
window.queryLocalFonts(). This method runs asynchronously
and returns an array of FontData objects representing the
fonts installed on the host system.
Because accessing the full list of local fonts carries fingerprinting
risks, calling queryLocalFonts() triggers a browser
permission prompt requiring explicit user consent. Additionally, the API
is only available in secure contexts (HTTPS).
Basic Enumeration Example
async function listSystemFonts() {
try {
// Request permission and query installed fonts
const availableFonts = await window.queryLocalFonts();
// Iterate through the font list and log metadata
for (const fontData of availableFonts) {
console.log(`PostScript Name: ${fontData.postscriptName}`);
console.log(`Full Name: ${fontData.fullName}`);
console.log(`Family: ${fontData.family}`);
console.log(`Style: ${fontData.style}`);
console.log('---');
}
} catch (error) {
if (error.name === 'NotAllowedError') {
console.error('Permission to access local fonts was denied by the user.');
} else {
console.error('Error querying local fonts:', error);
}
}
}Filtering Specific Fonts
The queryLocalFonts() method accepts an optional
configuration object containing a postscriptNames array.
This allows applications to request access to specific fonts rather than
iterating over the entire system registry:
async function getSpecificFont() {
const specificFonts = await window.queryLocalFonts({
postscriptNames: ['Roboto-Regular', 'Arial-BoldMT']
});
return specificFonts;
}Accessing Low-Level Font Data
Beyond basic metadata (family, style, names), the
FontData object allows applications to inspect and parse
raw font binary data using the blob() method. This is
essential for web applications that use custom OpenType/TrueType
rendering engines via WebAssembly (Wasm):
async function extractFontBytes(fontData) {
// Retrieve the raw SFNT container/table data
const blob = await fontData.blob();
const arrayBuffer = await blob.arrayBuffer();
// arrayBuffer can now be passed to low-level parsing libraries (e.g., HarfBuzz, FreeType)
return arrayBuffer;
}Privacy and Permissions
The Font Access API implements several controls to protect user privacy:
- Explicit User Permission: Browsers require the user
to explicitly grant the
local-fontspermission before any font data is returned. - Permission Status Queries: Applications can use the
Permissions API
(
navigator.permissions.query({ name: 'local-fonts' })) to check the current access state before invoking the prompt. - Permissions-Policy Support: Document owners can
control Font Access availability in embedded
<iframe>elements using thelocal-fontsdirective in the HTTPPermissions-Policyheader.