Benefits of header-only libraries

There are situations when a header-only library is the only option, for example when dealing with templates.

Having a header-only library also means you don't have to worry about different platforms where the library might be used. When you separate the implementation, you usually do so to hide implementation details, and distribute the library as a combination of headers and libraries (lib, dll's or .so files). These of course have to be compiled for all different operating systems/versions you offer support.

You could also distribute the implementation files, but that would mean an extra step for the user - compiling your library before using it.

Of course, this applies on a case-by-case basis. For example, header-only libraries sometimes increase code size & compilation times.


Benefits of header-only library:

  • Simplifies the build process. You don't need to build the library, and you don't need to specify the compiled library during the link step of the build. If you do have a compiled library, you will probably want to build multiple versions of it: One compiled with debugging enabled, another with optimization enabled, and possibly yet another stripped of symbols. And maybe even more for a multi-platform system.

Disadvantages of a header-only library:

  • Bigger object files. Every inline method from the library that is used in some source file will also get a weak symbol, out-of-line definition in the compiled object file for that source file. This slows down the compiler and also slows down the linker. The compiler has to generate all that bloat, and then linker has to filter it out.

  • Longer compilation. In addition to the bloat problem mentioned above, the compilation will take longer because the headers are inherently larger with a header-only library than a compiled library. Those big headers are going to need to be parsed for each source file that uses the library. Another factor is that those header files in a header-only library have to #include headers needed by the inline definitions as well as the headers that would be needed had the library been built as a compiled library.

  • More tangled compilation. You get a lot more dependencies with a header-only library because of those extra #includes needed with a header-only library. Change the implementation of some key function in the library and you might well need to recompile the entire project. Make that change in the source file for a compiled library and all you have to do is recompile that one library source file, update the compiled library with that new .o file, and relink the application.

  • Harder for the human to read. Even with the best documentation, users of a library oftentimes have to resort to reading the headers for the library. The headers in a header-only library are filled with implementation details that get in the way of understanding the interface. With a compiled library, all you see is the interface and a brief commentary on what the implementation does, and that's usually all you want. That's really all you should want. You shouldn't have to know implementation details to know how to use the library.