I developed connect-fonts for Mozilla Persona over 6 months ago but have never officially released it. Since the project has proven itself both useful and stable, I'd like to share it with the world.

Connect-fonts makes it a snap for Connect/Express applications to self host web fonts. By using connect-fonts, you are relieved from the difficult tasks of manually creating cross-browser font CSS and serving web font files with the correct headers. The middlware takes care of both.

In addition, connect-fonts makes enables you to serve minimal, locale specific font packs to your users. Why serve all Latin glyphs to all users if only the English, German (or your language) glyphs are needed? Serving fonts that contain only the glyphs needed for a user's locale can result in huge performance gains for your page's load time.

Why host your own fonts when Google (or Adobe, or FontSpring or somebody else) can do it for you?

There are two primary reasons to host your own fonts: performance and privacy.

Even though Google's font server is fast, it was freqently the slowest part of Persona's load time. We saw significant performance increases after moving fonts onto our own servers.

Next, privacy. For many privacy sensitive applications, embedding 3rd party content is a non-starter and self-hosting all content is the only way to go.

How does it work?

Connect-fonts watches incoming traffic for specially formatted fonts.css requests. Upon match, a CSS response is generated and served to the user. The CSS contains @font-face declarations tailored to the user's browser.


An optional locale can be specified to serve font files that contain only the glyphs needed for the user's language:


An example route (with language specified) is:


When requested, this results in CSS that looks like:

/* Generated by node-font-face-generator */
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans'),
       url('/fonts/en/opensans-regular.woff') format('woff'),
       url('/fonts/en/opensans-regular.ttf') format('truetype');
@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 700;
  src: local('Open Sans Bold'),
       url('/fonts/en/opensans-bold.woff') format('woff'),
       url('/fonts/en/opensans-bold.ttf') format('truetype');
CSS served to Firefox for /en/opensans-regular,opensans-bold/fonts.css

When content is rendered, the browser first checks to see if the fonts are installed locally. If so, those fonts are used and no additional network requests are made. If the fonts are not available, the browser will fall back to requesting the remote fonts.

Using connect-fonts

  1. Install the middleware

    $ npm install connect-fonts

  2. Install a font-pack. A list of fontpacks can be found on connect-fonts.org/families.

    $ npm install connect-fonts-opensans

  3. Include connect-fonts in your server code.

    const font_middleware = require("connect-fonts");
  4. Include the font packs.
    const opensans = require("connect-fonts-opensans");
  5. Add a middleware by calling the setup function.
        fonts: [ opensans ],
        allow_origin: "https://exampledomain.com",
        maxage: 180 * 24 * 60 * 60 * 1000,   // 180 days
        compress: true

More info

More info, including advanced usage and how to create a font pack can be found on connect-fonts.org. Jared Hirsch did a great in-depth analysis of the performance benefits of connect-fonts serving subsetted fonts over at Mozilla Hacks.


The source can be found on GitHub at https://github.com/shane-tomlinson/connect-fonts. Tools for working with font packs can be found at https://github.com/shane-tomlinson/connect-fonts-tools