FontCap

A desktop app that keeps one font library on a Mac, a Windows workstation and a Linux laptop at once, so a typeface installed on any of them is installed on all of them. Identity, product, all three builds and the site, made solo and given away.

FontCap project image
Project
FontCap, self-initiated
Sector
Design tools and typography
Services
Identity, product design, desktop app, website
Live at
fontcap.com

The fonts were already bought and already installed. They were just installed on one machine, and the work was happening on another.

Deliverables
  • Identity, logomark and app icon
  • Product design across five screens
  • Electron app for macOS, Windows and Linux
  • Font scanning, hashing and install services
  • Supabase auth and database, Cloudflare R2 storage
  • Landing page, brand motion and social
Overview

A licensed typeface is a file in a folder on one computer. You buy it once, you install it once, and the second machine you sit down at does not have it. The usual fixes are all bad in the same way: a shared drive somebody has to remember to update, a zip emailed to yourself, or a subscription manager that wants to own the library it is holding.

FontCap reads the font directories the operating system already uses, hashes what it finds, uploads each distinct file once, and installs it on the next machine that asks for it. On this Mac that is 2,644 fonts, 2,607 of them synced, against a Windows workstation carrying the same set.

It is free, MIT licensed and self hostable, and that was settled before the first screen was drawn. A tool that holds your type library should not be able to hold it hostage. The way to prove that is to publish the source and let anyone point it at their own database and their own bucket.

An F caught inside a C

The mark is a capital F set inside an open C, drawn as one stroke that breaks and turns back on itself. C for cap, F for font, and the break is where the two letters hand off to each other. At a distance it should read as one monogram rather than as two letters stacked, which is the test a mark like this either passes or does not.

The C is doing a second job. It closes around the F rather than sitting beside it, so the mark reads as one letter holding another: a font, captured. That is what the app does, and it is the reason the C is drawn open at the top with the stroke turning back inward instead of as a closed ring. A ring would be a badge. A bracket that has caught something is the product.

In a single colour the F crossbar and the C terminal want to merge, so the two colour lockup separates them: the F in blue, the C in black. Above roughly forty pixels either version holds. Below it the two colour one is the safer choice. That is the whole rule, and it is the only rule the mark needs.

The lockup
The mark alone
The app icon, modelled and rendered rather than drawn flat
The C draws itself, the F rises into it, and the two resolve into the app icon
#3B82F6
#1D1D1F
#F5F5F7
#86868B
#34C759

The preview is the font, not a picture of it

Every card sets its own specimen in its own typeface. That sounds obvious and it is the constraint the whole app is built on: the renderer can only preview a face the operating system has already loaded, so scanning and installing are not features bolted onto a browser window, they are the floor the interface is standing on.

A card carries four things and refuses a fifth. The specimen set in the face, the family name, up to three tags read out of the file, and a dot that is green when the font is present on this device. Foundry, licence and date added all get asked for, and most font files simply do not carry them. A column that is empty on most rows makes the grid worse, not more informative.

Hovering is four things over two hundred milliseconds: the border goes blue at thirty percent, a blue tinted shadow rises under the card, the card lifts two pixels, and the specimen turns from near black to the interface blue. The lift is what makes it read as an object you could pick up. The colour change is what keeps the type as the subject.

Four moves over two hundred milliseconds, once per card
The library, 2,644 fonts
Search, ten of them matching

The same font, under four names

A library carried between machines for a decade is full of duplicates that are not duplicates by name. Helvetica.ttf, helvetica.ttf, Helvetica-01.ttf and a copy inside a client folder from 2019 are one file wearing four filenames. Uploading them as four costs storage, costs bandwidth, and puts four identical rows into a list that is already thousands long.

So every file is hashed with SHA-256 before anything leaves the machine, and the hash is the identity. A file already in the library uploads nothing and simply registers itself against the device. The same check runs the other way on install, so a sync never writes a file that is already sitting in the system font directory under a different name.

This is the least visible part of the app and the most load bearing. Without it, adding a machine to a library of two and a half thousand fonts means two and a half thousand uploads, every time.

One file, four filenames, one upload

Three operating systems, three ideas of where a font lives

macOS, Windows and Linux each keep fonts somewhere different, install them differently, and disagree about what counts as installed at all. The scanner reads the system and user directories on all three. The installer writes to the per user location rather than the system one, so FontCap never needs an administrator prompt to do its ordinary job.

Electron is what lets one codebase reach all three, and it is also why the app is a hundred and eighty megabytes. That is a real cost and it bought a real thing: the Windows machine and the Mac in the Devices panel are running the same build, and a fix lands on both at once.

The Devices panel is the part that had to be honest. Each machine reports what it is actually holding rather than what the library thinks it should be holding, so a device that has fallen behind says so in numbers instead of showing a tick. A sync tool that reports its own optimism is worse than no sync tool.

Devices, reporting what each machine actually holds

A landing page with one job

fontcap.com exists to put the right installer in somebody’s hand. It detects the platform and leads with that button, with the other two beside it rather than folded behind a menu, because downloading for a machine you are not currently sitting at is an ordinary thing to be doing.

The page is set in DM Sans on white and uses the app’s blue and no other colour. Six bands: the proposition, the argument for a font manager over a sync folder, three steps, the feature grid, the technical detail, and the download again at the bottom. Nothing on it moves for its own sake.

It is a separate build from the app, deliberately. The app is Electron and ships as a binary on a release cycle. The site is static and can change the same afternoon somebody asks a question the copy does not answer.

The platform button leads
Scan, upload, install

Shipping it in the open

The repository is public and MIT licensed, and the README is written for somebody standing the whole thing up themselves rather than for me remembering how it works six months later. The database schema, the environment variables, the bucket permissions, the exact commands for each platform build.

That decides where the secrets live. Nothing is committed, every credential is an environment variable, and the key that does ship inside the binary is a public one by design: what protects a person’s library is row level security on the database and per user paths in the bucket, not the key being hard to find. A tool people are invited to self host has to be built that way from the start, because you cannot add it later without breaking everybody who already trusted it.

Every build goes out through GitHub Releases with a SHA-256 printed beside each file, which is the same check the app runs on a font and for the same reason: you should be able to tell whether the bytes you got are the bytes that were sent.

Every build published, with a checksum beside each file

Where it is now

Version 1.3.0, sixteen release artefacts across the three platforms, first commit in October 2025. A disk image for macOS, a zip for Windows, an AppImage and Debian packages for Linux on both Intel and ARM.

Free, and the whole thing runs on somebody else’s infrastructure if they want it to. A database project for auth and records, an object storage bucket for the files, both on free tiers that comfortably hold a personal library.

It has been carrying my own library since, 2,644 fonts across a Mac and a Windows workstation, which is the only test of a tool like this that means very much.