Skip to content
HarfBuzz as OpenType engine in LuaTeX, LaTeX, and ConTeXt
Lua TeX Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


HarfBuzz as OpenType engine in LuaTeX, LaTeX, and ConTeXt




HarfBuzz is an OpenType text shaping engine used in software like Firefox, Chromium, XeTeX, and LibreOffice.

LuaTeX, LuaLaTeX, and ConTeXt

LuaTeX is a version of TeX that uses Lua as an embedded scripting language. Via the use of Lua scripts the TeX functionality can be extended in various ways, for example with respect to the rendering of OpenType fonts.

Luatex-harfbuzz as alternative rendering engine

LuaTex, LuaLaTeX, and ConTeXt already have a powerful rendering engine at their disposal, namely the ConTeXt OpenType engine, which is able to handle many different font features and scripts. Luatex-harfbuzz provides the use of HarfBuzz as alternative rendering engine.

The approach chosen is a hybrid one in which much of the processes – except the actual rendering, which is done by HarfBuzz – relies on ConTeXt code that is already at hand in LuaTex, LuaLaTeX, and ConTeXt.

Installing and using Luatex-harfbuzz

There are several ways of installing and using luatex-harfbuzz. Binding HarfBuzz to LuaTex can be done via FFI and via SwigLib. The route via FFI is much more simple because it only involves installing HarfBuzz whereas the route via SwigLib also involves compiling libraries. Quick results can therefore be obtained via FFI. However, the use of FFI is sometimes advised against because of security risks.

Feel free to add

This reference is written for the use of luatex-harfbuzz on Mac OS X. In principle, however, the approach should also work on other platforms. Please feel free to add instructions for other platforms.

In principle, the applied method is not restricted to the HarfBuzz engine. Please feel free to add materials for other OpenType engines (such as graphite2, which is also available in Homebrew).

Quick results via FFI

Install MacTeX 2019, Homebrew, and HarfBuzz

Download MacTeX.pkg (2019) from and run the installer. When asked, also install the Mac OS X command line developer tools.

Install Homebrew:

/usr/bin/ruby -e "$(curl -fsSL"

Install HarfBuzz (the result is /usr/local/lib/libharfbuzz.0.dylib):

brew install harfbuzz

Prepare LuaJitLaTeX

MacTeX 2019 does not create a luajitlatex executable and its accompanying format file. These can be created manually:

cd /usr/local/texlive/2019/texmf-var/web2c/luajittex/
sudo luajittex -ini -jobname=luajitlatex \* lualatex.ini
cd /usr/local/texlive/2019/bin/x86_64-darwin
sudo ln -s luajittex luajitlatex
sudo texhash

Test FFI

Now luatex-harfbuzz should already work via FFI, which can be tested by means of the example files in the luatex-harfbuzz folder. FFI requires that LuaTeX, LuaLaTeX, and ConTeXt are executed using JIT. Moreover, due to new security restrictions luajittex and luajitlatex have to carry the --shell-escape flag:

luajittex --shell-escape example-luatex-ffi
luajitlatex --shell-escape example-lualatex-ffi
contextjit example-context-ffi

Note that the ConTeXt OpenType engine is in constant development and that the version installed by means of MacTeX 2019 is not the most recent one. For a fair comparison between the ConTeXt OpenType engine and HarfBuzz, a recent beta version should be used. The ConTeXt OpenType engine can be updated by updating ConTeXt. For instructions, see the manual of luatools. (This manual is also helpful for tackling problems related to running ConTeXt.) Additionaly, for LuaLaTeX the luaotfload package can be updated, for instance by means of the TeX Live Utility.

SwigLib bindings

Alternative to the FFI route, binding HarfBuzz to LuaTex can also be done via SwigLib. This involves:

  • Installing MacTeX 2019, Homebrew, and HarfBuzz
  • Compiling libraries

Install MacTeX 2019, Homebrew, and HarfBuzz

See above.

Compile libraries

The route via SwigLib requires the compilation of libraries (i.e. .so files on Mac OS X or .dll files on MS Windows). In what follows, two approaches are described to build .so files. The first is luaharfbuzz, which is developed by Deepak Jois. The second, more complicated approach is more in line with the SwigLib project and is based upon example code by Luigi Scarso (altough several adjustments were necessary to have that code work with HarfBuzz). This approach requires the files in the swiglib folder.


Install Lua:

brew install lua

Install luarocks:

brew install luarocks

Install luaharfbuzz:

sudo luarocks install luaharfbuzz

Create the folder lib/luatex/lua/swiglib/hb_deepak/ in /usr/local/texlive/2019/bin/x86_64-darwin/ and copy the generated (in /usr/local/lib/lua/5.3) to that folder.

Test luaharfbuzz

Now luatex-harfbuzz should work via luaharfbuzz, which can be tested by means of the example files in the luatex-harfbuzz folder:

luatex example-luatex-swig-dj
lualatex example-lualatex-swig-dj
context example-context-swig-dj

Install Lua (if not already done during installation of luaharfbuzz):

brew install lua 

Install swig:

brew install swig

Install pkgconfig:

brew install pkgconfig

Download the newest tarball release (.tar.bz2) of HarfBuzz from

Move the src folder to the swiglib folder in which the .so file will be build (this is the folder that, amongst others, contains core.i).

Build (if during this process lua.h, luaconf.h, and lauxlib.h are not found, it might help to make a symlink to them in /usr/local/include: ln -s /usr/local/include/lua/lua.h /usr/local/include && ln -s /usr/local/include/lua/luaconf.h /usr/local/include && ln -s /usr/local/include/lua/lauxlib.h /usr/local/include):

swig -cpperraswarn -c++ -lua core.i

Rename the generated to

Create the folder lib/luatex/lua/swiglib/hb/ in /usr/local/texlive/2019/bin/x86_64-darwin/ and copy the generated to that folder.

Test SwigLib

Now luatex-harfbuzz should work via the SwigLib binding of, which can be tested by means of the example files in the luatex-harfbuzz folder:

luatex example-luatex-swig
lualatex example-lualatex-swig
context example-context-swig


Kai Eigner
TAT Zetwerk

You can’t perform that action at this time.