Molochou
← All work

Fontshift

Swaps every font in a Figma file at once, and maps the weights so nothing turns to mush.

Design toolsDesign & engineering2026Figma CommunityGitHub
Fontshift

Changing a typeface across a finished file is a day of clicking, and the part that breaks is never the family. It is the weights. Semibold in one font is not semibold in another, so a naive swap flattens the hierarchy the file was built on.

Year
2026
Role
Design & engineering
Type
Figma plugin, free with no limits
Runs
Offline, nothing leaves the file

Theproblem

Figma replaces fonts one style at a time, and any weight with no exact name in the target family quietly falls back to regular. On a large file that is hundreds of small corrections afterwards, in places nobody remembers to look.

WhatIdid

The family is what you notice, the weights are what you were reading
01

The family is what you notice, the weights are what you were reading

Both of these are the same typeface. The difference is that one kept four weights and the other lost three of them on the way across, which is what a swap that only moves the family does. Nothing looks broken afterwards, which is exactly the problem: the file still reads as a design, just one where nothing is more important than anything else.

02

What is actually in there

Select a frame and the panel lists the fonts inside it, family and style as separate things, counted and sorted by how much of the selection each one holds. There is no scan button, because the list follows the selection: change what you have selected and it changes with it. A button you have to remember to press is a button that is out of date half the time.

03

Every way a file spells the same weight

A style is a word, and the words disagree. Thin and Hairline are the same thing. So are Semibold and Demibold, Extrabold and Ultrabold, Black and Heavy, Regular and Normal and Book. Each of them is mapped onto one number, and a style literally called 600 is read as 600. Until that happens there is no way to compare two families at all.

04

Nearest weight wins, and italic is not negotiable

Every style the target family offers is scored: the distance from the weight you had, plus a thousand if one is italic and the other is not. A thousand is more than the distance between the lightest and the heaviest thing a family owns, so an upright can never beat a slanted one on weight alone. Everything else is a compromise; that one is not.

05

One press, and the whole selection

Pick the family you are leaving, search out the one you are moving to, press once. Every text layer under the selection is walked and each style is resolved on its own rather than once for the family. What comes back is how many layers changed and, if anything refused, what it said.

06

A layer is not one font

A sentence with a bold phrase in the middle is one text layer with several fonts inside it, and Figma answers questions about it with "mixed" and nothing else. So the layer is read a character at a time, neighbours carrying the same font are gathered into a run, and each run is matched and written separately. A run belonging to a family you did not ask about is left exactly where it is.

Two lists, one search, one button
07

Two lists, one search, one button

The window is 560 by 480 and holds what is there, what it could become, and the verb. No settings, no preview step, no report. A tool used for thirty seconds in the middle of somebody else’s work cannot afford to teach anything, so there is nothing to learn.

Underthehood

Figma will not let you write text you have not loaded

Every font already used in a layer has to be loaded before a single character of it can be touched, including the ones being replaced. So the swap is not a loop over layers, it is a loop that collects fonts, waits for all of them, and only then writes. Skip that and it fails on the first mixed paragraph it meets.

Unknown is treated as regular, on purpose

A style name nobody has heard of resolves to 400 rather than throwing. It is the wrong answer sometimes and it is a visible one: a heading that came back regular is noticed and corrected in a second, whereas a swap that stopped halfway through leaves a file in a state nobody can describe.

It changes the font and nothing else

No resizing, no line height, no letter spacing, no tidying up of anything it passes on the way. Every layer that comes out different came out different in one property, which is the only reason the result can be reviewed at all.

Free, offline, no limits

The manifest declares no allowed domains, so nothing is uploaded, nothing is counted and there is nothing to sign in to. It runs against the open file and stops when it is done.

Next projectSlide ImportDesign tools