{"id":24780,"library":"ufoLib2","title":"ufoLib2","description":"ufoLib2 is a UFO font processing library for reading, writing, and manipulating Unified Font Object (UFO) files. It provides Python objects for font, layer, glyph, and other UFO structures with lazy loading and efficient serialization. Current version: 0.18.1. Requires Python >=3.9. Maintained by the fonttools project; release cadence is irregular with several minor releases per year.","status":"active","version":"0.18.1","language":"python","source_language":"en","source_url":"https://github.com/fonttools/ufoLib2","tags":["UFO","font","type design","fonttools","font processing"],"install":[{"cmd":"pip install ufoLib2","lang":"bash","label":"Core installation"},{"cmd":"pip install ufoLib2[converters]","lang":"bash","label":"With JSON/MessagePack support via cattrs"},{"cmd":"pip install ufoLib2[json,msgpack]","lang":"bash","label":"Full extras"}],"dependencies":[{"reason":"Required for UFO data structures and glyph drawing","package":"fonttools","optional":false},{"reason":"Used internally for filesystem abstraction (deprecated as of 0.18.0, replaced by tempfile.TemporaryDirectory)","package":"fs","optional":false}],"imports":[{"note":"Font is exported at package level since v0.10.0; direct import from objects works but is not recommended.","wrong":"from ufoLib2.objects import Font","symbol":"Font","correct":"from ufoLib2 import Font"},{"note":"Glyph is not exported at package level; must import from ufoLib2.objects.","wrong":"from ufoLib2 import Glyph","symbol":"Glyph","correct":"from ufoLib2.objects import Glyph"},{"note":"Layer is not exported at package level; must import from ufoLib2.objects.","wrong":"from ufoLib2 import Layer","symbol":"Layer","correct":"from ufoLib2.objects import Layer"}],"quickstart":{"code":"from ufoLib2 import Font\n\n# Create a new font\nfont = Font()\nfont.info.unitsPerEm = 1000\n\n# Save to a temporary path (will create .ufo directory)\nimport tempfile\nwith tempfile.TemporaryDirectory() as tmpdir:\n    ufo_path = f\"{tmpdir}/MyFont.ufo\"\n    font.save(ufo_path)\n    print(f\"Saved to {ufo_path}\")\n\n# Open an existing UFO\nfont2 = Font.open(ufo_path)\nprint(font2.info.unitsPerEm)","lang":"python","description":"Create a new UFO font, set unitsPerEm, save to a temporary directory, then reopen it."},"warnings":[{"fix":"Upgrade Python to 3.9 or later.","message":"Python 3.8 support dropped in v0.18.0. Use Python >=3.9.","severity":"breaking","affected_versions":">=0.18.0"},{"fix":"Replace usage of tempfs with tempfile.TemporaryDirectory.","message":"The 'fs' module (import fs) will be removed; replaced with tempfile.TemporaryDirectory. Do not rely on fs internals.","severity":"deprecated","affected_versions":">=0.18.0"},{"fix":"Access properties or call .load() to trigger loading. Use Font.open(ufo, lazy=False) to disable lazy loading.","message":"Font objects are lazily loaded by default. Modifying glyphs or layers may require explicit loading.","severity":"gotcha","affected_versions":"all"},{"fix":"Use font.save('/path/to/MyFont.ufo') which creates a directory.","message":"Saving a UFO creates a directory (UFO format) not a single file. Ensure the save path ends with .ufo and the parent directory exists.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure cattrs >=1.10.0 is installed if using converters extra.","message":"cattrs minimum version upped to 1.10.0 as of v0.13.1. Older cattrs may cause errors with converters.","severity":"breaking","affected_versions":">=0.14.0"},{"fix":"Change import to 'from ufoLib2 import Font'.","message":"Use of 'from ufoLib2.objects import Font' is discouraged; prefer 'from ufoLib2 import Font'.","severity":"deprecated","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"pip install ufoLib2","cause":"Library not installed.","error":"ModuleNotFoundError: No module named 'ufoLib2'"},{"fix":"from ufoLib2.objects import Glyph","cause":"Glyph is not exported at package level.","error":"AttributeError: module 'ufoLib2' has no attribute 'Glyph'"},{"fix":"font.save('/path/to/font.ufo')","cause":"Trying to save with a file path as argument without keyword? Actually save only takes the path as positional.","error":"TypeError: save() takes 1 positional argument but 2 were given"},{"fix":"Ensure the UFO is valid; check ufo/lib/formatversion.txt. ufoLib2 supports UFO v3 and v2.","cause":"UFO file has format spec version that is not supported or malformed.","error":"ufoLib2.errors.UFOError: Invalid UFO version: 3"},{"fix":"Use 'from ufoLib2 import Font' instead.","cause":"Wrong import path or outdated version.","error":"ImportError: cannot import name 'Font' from 'ufoLib2.objects' (unknown location)"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}