New: Command-line tool for Glyphs

We have a new command-line tool with which you can export Glyphs source files to OpenType fonts. This is what it looks like:

Install the tool with pip:

python3 -m pip install glyphs-cli

Once installed, you can use the glyphs command.

Exporting fonts

This command-line tool itself does not know how to export fonts. Instead, it uses the Glyphs app installed on your Mac. That way, the results are the same whether exporting from the Glyphs app or from the command-line tool.

# export using latest Glyphs 3 version that is installed on the Mac
glyphs export --app 3 SomeFont.glyphs

(The Glyphs app does not need to be running and is not opened when using this command.)

Further, the tool can select any other Glyphs version. If you have multiple Glyphs app versions installed, you can choose among them.

# export using a specific version
glyphs export --app 3.4 SomeFont.glyphs
# export using a specific build number
glyphs export --app 3432 SomeFont.glyphs
# export using a specific app
glyphs export --app '/Applications/Glyphs 3.app' SomeFont.glyphs

This allows you to edit files with one Glyphs version and use the tool to export the files using another Glyphs version. That can be useful in a team where different people might use different Glyphs app versions but you still want everyone to export using the exact same version.

When no --app option is given, the tool uses the Glyphs version with which the file was last saved:

$ glyphs export SomeFont.glyphs
using Glyphs 3.5 (3512)
...

Use the --format option to choose between PostScript/CFF-style (cff, default), and TrueType-style (tt) OpenType fonts:

# export .ttf files
glyphs export --app 3 --format tt SomeFont.glyphs

Use the --output option to export to a specific directory instead of the current directory:

# export font files to the Desktop
glyphs export --app 3 --output ~/Desktop SomeFont.glyphs
GitHub Actions sample workflow

If you use GitHub to host your font project, you can use the following workflow to create font files for every commit you push. Adapt as needed:

name: Export Fonts

env:
  GLYPHS_BUILD: "3516"

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

jobs:
  export:
    runs-on: macos-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.x'

      - name: Preparation
        run: mkdir Output

      - name: Install glyphs-cli
        run: pip install glyphs-cli

      - name: Install Glyphs version
        run: glyphs version install $GLYPHS_BUILD

      - name: Export
        run: glyphs export -a $GLYPHS_BUILD -o Output *.glyphs

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: export
          path: Output/

Managing Glyphs versions

Use the glyphs version family of commands to list, install, and uninstall Glyphs versions:

# show installed versions
glyphs version list
# show installed versions and downloadable versions
glyphs version list --remote

# download and install a specific version
glyphs version install 3432
# download and install the latest version matching a version number
glyphs version install 3.3

# uninstall a specific version
glyphs version uninstall 3432
# uninstall all versions matching a version number
glyphs version uninstall 3.3

These commands do not install full Glyphs apps. Instead, they install just the part of a Glyphs app that is required for the tool’s usage. Therefore, less storage space is used for each installed version. The glyphs tool manages these versions for you. When using glyphs version uninstall, only these managed versions are uninstalled, not the Glyphs apps you have installed manually.

If you want to install a full Glyphs app that you can also use outside the tool, pass the --app option when installing:

$ glyphs version install --app 3.3
fetching index
downloading version Glyphs3.3.1-3343
######################################################## 100%
installing application /Applications/Glyphs 3.3.1-3343.app

Learning more

Ask the tool for help with --help at the end of a command. It will output all possible arguments, options, and subcommands:

glyphs --help
glyphs export --help
glyphs version --help
glyphs version install --help
...

Next steps

When anything is unclear or could be explained better, feel free to ask here on the forum. This tool is still in an early phase so I am sure there is plenty to be improved. One thing that is currently missing: If you run plug-ins such as filters on export, those are currently not supported yet.

It works best with recent Glyphs versions (3.3, 3.4, 3.5) and less well with older versions.

Currently, it’s available using Python’s pip, but we also intend to provide a direct download and maybe other package managers as well.

Exporting is the main feature of the tool now, but we could think about also offering other Glyphs capabilities. Let us know what kind of glyphs ... subcommands would be valuable to your workflow.

10 Likes

This is absolutely incredible. Amazing work, thank you!

1 Like

One thing I would really, really appreciate (in order to be able to use this) would be the possibility to run filters on the font before export. Such as nested component removal. Although I assume that these are applied when set as filter arguments in the instance definitions.

Is a more enhanced feature set planned? If so, what ideas are you thinking of?

1 Like

While custom plug-ins are on the roadmap, they are a bit tricker to implement. Especially since most custom plug-ins are written in Python, which introduces further complexity. Still, should all be possible, I just need a good plan and more time.

Note that build-in export filters do work since no custom plug-ins need to be loaded for those.

There are many possibilities. I would be most interested in outside feedback in order to know whether my general direction for the tool aligns with users needs or if it would be better to focus on other areas.

For the export command, I would like to have a config file where you can configure the instances and export paths and other settings. A bit like a Glyphs project but tailored for a command-line tool. There is already the --config option, but it is not well documented yet and I still don’t have a clear idea how to best structure that configuration.

This sounds great. Essentially, this would be a Glyphs-native alternative to fontmake, which could use .glyphsproject files (or the settings in the Glyphs file) instead a of a designspace file.

As you mention, a config for the directory map would hé extremely useful. I have this set up in my own export plugin, as a YAML config.

In any case, I am very interested in utilising this, it’s just not yet useful to me. Keep us posted!

That’s interesting! That would be a huge improvement for CI/CD generated fonts and remove the dependency to fontmake and designspace format.
Looking forward to test it!

CI/CD is very much one of the focus areas for this tool. Have a look at the GitHub Actions workflow that I have included in the first post and adapt as needed. I am sure similar workflows would be possible on other CI/CD providers.

This tool is great, it’s something I’ve thought would be useful for a long time! Seconding what @SCarewe said that running non-built-in filters on the fonts before export is a feature that would be very useful. Additionally having something like a run-script command where you could point to a Glyphs file and to a python script to run within the context of that file (like when you run a script normally) would be extremely useful and mean we wouldn’t need to use tools like glyphsLib to programatically edit Glyphs files.

Thanks for building this! I’d definitely use it. On priorities, I’d emphasize:

  • Custom Filters – essential
  • Config Files – essential

I agree with Sebastian that these are the highest-impact additions.

Just shouting some other thoughts into the void:

  • A simple command-chaining syntax for multi-format exports (e.g., exporting different formats to different folders in one call) would be really useful—something lighter than requiring a config file or long command chains.
  • Some form of validation: report compatibility issues (or any issues) that break exporting, maybe even report inconsistencies like missing glyphs when running on multiple files (not really thought that through yet, just brainstorming)
  • Caching layer: Skip re-exports if source hasn’t changed (useful for CI/CD)
  • Diff command, though that would mostly make sense with gitted files, and then one can just use git for it, but maybe with a wrapper that can present the diffs in a cleaner way (thinking of a CL version of your Light Table)
  • TTX integration: direct output of all or defined font tables
  • List command: Query glyphs, instances, masters, axes without exporting
  • Feature file extraction (not using it myself, but see it often as a request here in the forum)
  • Metadata output (JSON/YAML/SVG export of glyph data)
  • Watch mode: Regenerate fonts on file changes
  • Font subsetting based on glyph lists

The config file could include any or all of those optionally.

Just thoughts, did not try it yet so maybe some of those are already there or on your roadmap :slight_smile:

1 Like

Noted, custom filters for export are a priority.

I can imagine a command like

glyphs edit SomeFont.glyphs --script SomeScript.py

where the file is opened, the script is executed, and then the GSFont is saved back to the file (with options to save to a different file or not save at all).

In that case I would run the glyphs export command twice with different format and output options. However, I can add the option to specify both CFF and TrueType for a single export run.

The tool reports the same errors and warnings you get when exporting from Glyphs, including compatibility or other issues blocking the export. The tool will always return with a non-zero status code when something went wrong.

I think that is handled best outside the glyphs tool. Create a checksum or compare modification dates or whatever best serves your needs and then only conditionally run the tool.

I have a CLI version of Light Table, but never got around to polishing and publishing it. Maybe something worth investigating when I can find some time.

What TTX-specific feature would like to see? You can use TTX with the exported font files.

Those objects already exist in the .glyphs/fontinfo.plist file and can be extracted using fairly minimal Python scripting. What would be your use cases? Would you like to view these values or is this mostly to pipe them to another command?

That could be useful.

Some potential, but also very broad. If there is anything is particular that you would need for your workflow, let me know. Specifics help, since there are, for example, many different ways an SVG can be created.

I would use a different tool for that. I can recommend watchexec, but there are others that do similar things.

watchexec -e glyphs -- glyphs export SomeFont.glyphs

I think this is possible using the custom config.

I would very strongly suggest that the default behaviour should be not to save it. This CLI editing would be most used during export – every single time, to run scripts (filters) on the font/instances.

For export, there is the glyphs export command. It could gain a --script option or similar.

glyphs edit is separate and would allow users to make edits to a file.

Ah, I see. Makes sense. Thanks!

Sounds good, although I do agree that the file should not be automatically saved unless we call something like GSDocument.save(). Because sometimes I need to run a script which does not edit the file, but create metadata, or generate a new version of the file and save it somewhere else on the disk, for example.

@FlorianPircher Also what is the status of this tool? Could we already use it in production for straightforward exporting, or would you not recommend it yet?

Yes, saving by default is probably not a good idea.

If you are using the current Glyphs version (3.4 or 3.5 beta), I think it can already work well in production. Still, this tool is new and so I expect it will not fully handle every type of file and workflow.

glyphs-cli 0.2.0 is out now. New:

  • support for custom plug-ins during export
  • ability to run a custom script before export
  • additional glyphs edit command to run a script without exporting

Install the latest version with

python3 -m pip install glyphs-cli --upgrade

Using plug-ins when exporting

glyphs export will now load all plug-ins installed for the selected app version before the font files are exported. This allows, for example, filter plug-ins to be applied using the “Filter” custom parameter of an instance.

You can be specific about which plug-ins to load. This can help by skipping plug-ins that are not needed and thus speed up the export command or when a plug-in is incompatible with the CLI tool:

glyphs export --plugins OptimizeStartNodes,Beowulferize SomeFont.glyphs

You can also load plug-ins that are not installed for the Glyphs app:

glyphs export --plugins app,tools/MyFilter.glyphsFilter SomeFont.glyphs

The app keyword here loads all of the plug-ins installed for the Glyphs app in addition to the plug-in at the specified file path.

Prevent plug-ins from being loaded by specifying an empty string:

glyphs export --plugins '' SomeFont.glyphs

Running a script before font export

Use the --script/-s option to specify a Python script that should be run before the font files are exported:

glyphs export --script SomeScript.py SomeFont.glyphs

The script can access the regular scripting API like any other Glyphs script or Macro Panel code. Note that in this case you cannot access user interface elements such as the window of the document.

The fonts are available using Glyphs.fonts, same as in regular scripting. If you are only exporting a single source file, it is also accessible as Font and Glyphs.font.

Feel free to modify the GSFont object as changed to it are not saved. Once the script finishes running, the font files are exported.

Running a script without exporting

If you want to run a script but do not need to export font files, use the new glyphs edit command. It behaves like the glyphs export command:

glyphs edit --script SomeScript.py SomeFont.glyphs

Like with the glyphs export command, you can supply one or more source files and access them as Glyphs.fonts.

Currently, you cannot save the changes made to the GSFont object. That is, font.parent.save() does not work yet. This will be addressed in a future version of the CLI tool.

Selecting a Python version

By default, the CLI tool will use the same Python version that is also configured for the selected app. You can choose a different Python version using the --python option:

glyphs export --python .../Python.framework/Versions/3.14/Python

This works for glyphs edit as well.

3 Likes

Fantastic work. And so fast!

Question: Is there a possibility to run a script on each exporting instance?

For example, I would like to remove small kerning pairs for each instance (not just masters). For this, I currently get an interpolated font for the GSInstance, process the kerning, and then export that font. That’s very slow, of course.

You need a filter for this.

And I would have to set this in every instance in the Glyphs file itself?

Or, actually, I could set that with a script in each instance using the CLI. That’s a workaround, thanks.