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: