Bulk Export Web Fonts Using FontForge Python

This guide provides a straightforward method for bulk converting desktop font formats (such as TTF and OTF) into modern web formats (WOFF and WOFF2) using FontForge's Python scripting module. By leveraging automated scripting, you can process entire directories of fonts within seconds, eliminating the need to manually export files one by one through the graphical user interface.

Prerequisites

Before running the batch export script, ensure you have FontForge installed on your system. FontForge bundles its own Python interpreter.

  • Linux: Install via package manager (e.g., sudo apt install fontforge python3-fontforge).
  • macOS: Install via Homebrew using brew install fontforge.
  • Windows: Download the installer from the official FontForge website. The Windows installation includes a ffpython.exe binary in its installation directory.

The Python Batch Script

Save the following code as convert_fonts.py. This script scans an input folder, detects all .ttf and .otf files, and exports both .woff and .woff2 files to a designated output folder.

import os
import sys
import fontforge

# Set directories
INPUT_DIR = "./input_fonts"
OUTPUT_DIR = "./output_webfonts"

# Formats to generate
EXPORT_FORMATS = ["woff", "woff2"]

def bulk_convert():
    if not os.path.exists(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)

    valid_extensions = (".ttf", ".otf")
    font_files = [f for f in os.listdir(INPUT_DIR) if f.lower().endswith(valid_extensions)]

    if not font_files:
        print("No compatible font files found in the input directory.")
        return

    for filename in font_files:
        source_path = os.path.join(INPUT_DIR, filename)
        base_name = os.path.splitext(filename)[0]

        try:
            # Open font
            font = fontforge.open(source_path)
            
            # Export to each target format
            for fmt in EXPORT_FORMATS:
                target_filename = f"{base_name}.{fmt}"
                target_path = os.path.join(OUTPUT_DIR, target_filename)
                
                font.generate(target_path)
                print(f"Generated: {target_filename}")

            font.close()
        except Exception as error:
            print(f"Failed to process {filename}: {error}")

if __name__ == "__main__":
    bulk_convert()

How to Execute the Script

Because FontForge relies on internal C libraries, standard system Python may not locate the fontforge module unless explicitly linked. Run the script using the FontForge binary runner to avoid import errors.

On Linux and macOS:

Run the script using FontForge's -script flag:

fontforge -script convert_fonts.py

On Windows:

Use the dedicated ffpython executable located inside your FontForge installation folder:

"C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe" convert_fonts.py

Key Considerations

  • WOFF2 Dependencies: Generating WOFF2 files requires that FontForge was compiled with the brotli library enabled. Most modern builds include this by default. If .woff2 output fails, check that your FontForge build supports it or update to the latest release.
  • Overwriting Files: The font.generate() method overwrites existing files with the same name in the output directory without prompting.
  • Metadata and Hinting: By default, FontForge preserves hinting, kerning tables, and font metadata during generation.