diff --git a/.gitmodules b/.gitmodules
index d5aa77cd1714a908dac4d84ea9bade7907bdacc7..6ae6b671d40bf11983f0df1c5c70aa714e78870d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -42,3 +42,6 @@
 	path = ext/Catch2
 	url = https://github.com/catchorg/Catch2.git
 	branch = devel
+[submodule "ext/freetype2"]
+	path = ext/freetype2
+	url = https://github.com/freetype/freetype2.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2ab4163e83d381c094db2b0225f397e9edeb5655..b8c9115d3d689c4572fefc966ede3f60f5031a49 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -314,6 +314,14 @@ add_library(lava::block ALIAS lava.block)
 
 message(">> lava::app")
 
+message(">>> freetype2")
+
+add_subdirectory(${LIBLAVA_EXT_DIR}/freetype2 freetype2 EXCLUDE_FROM_ALL)
+
+set_target_properties(freetype PROPERTIES FOLDER "lava/ext")
+
+message("<<< freetype2")
+
 set(IMGUI_FILES
         ${LIBLAVA_EXT_DIR}/imgui/imgui.cpp
         ${LIBLAVA_EXT_DIR}/imgui/imgui.h
@@ -321,6 +329,8 @@ set(IMGUI_FILES
         ${LIBLAVA_EXT_DIR}/imgui/imgui_tables.cpp
         ${LIBLAVA_EXT_DIR}/imgui/imgui_widgets.cpp
         ${LIBLAVA_EXT_DIR}/imgui/imgui_demo.cpp
+        ${LIBLAVA_EXT_DIR}/imgui/misc/freetype/imgui_freetype.cpp
+        ${LIBLAVA_EXT_DIR}/imgui/misc/freetype/imgui_freetype.h
         )
 
 source_group("imgui Files" FILES ${IMGUI_FILES})
@@ -356,6 +366,7 @@ target_link_libraries(lava.app
         lava::asset
         lava::block
         lava::frame
+        freetype
         )
 
 set_target_properties(lava.app PROPERTIES FOLDER "lava")
diff --git a/DOCS.md b/DOCS.md
index 95d6d5ace0a896dbdffee765225321c5a078aecc..1d9417e79baeeaf5e260333a2eac7ec85b53ab68 100644
--- a/DOCS.md
+++ b/DOCS.md
@@ -430,6 +430,11 @@ int main(int argc, char* argv[]) {
   [![frame](https://img.shields.io/badge/lava-frame-red.svg)](liblava/frame/frame.hpp)
 
 * [Catch2](https://github.com/catchorg/Catch2) &nbsp; **A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD** &nbsp; *BSL 1.0*
+
+* [freetype2](https://github.com/freetype/freetype2) &nbsp; **FreeType is a freely available software library to render fonts** &nbsp; *FTL*
+
+  [![imgui](https://img.shields.io/badge/lava-imgui-brightgreen.svg)](liblava/app/imgui.cpp)
+
 * [glfw](https://github.com/glfw/glfw) &nbsp; **A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input** &nbsp; *zlib*
 
   [![frame](https://img.shields.io/badge/lava-frame-red.svg)](liblava/frame/frame.cpp) [![input](https://img.shields.io/badge/lava-input-red.svg)](liblava/frame/input.cpp) [![window](https://img.shields.io/badge/lava-window-red.svg)](liblava/frame/window.cpp)
diff --git a/ext/freetype2 b/ext/freetype2
new file mode 160000
index 0000000000000000000000000000000000000000..f9f6adb625c48ef15b5d61a3ac1709a068ea95a3
--- /dev/null
+++ b/ext/freetype2
@@ -0,0 +1 @@
+Subproject commit f9f6adb625c48ef15b5d61a3ac1709a068ea95a3
diff --git a/liblava/app/imgui.cpp b/liblava/app/imgui.cpp
index 27fd8e06d669af714ce1f308fa4765531eed1e24..028108b04a8dd43b34a3431584be1356ac54e832 100644
--- a/liblava/app/imgui.cpp
+++ b/liblava/app/imgui.cpp
@@ -18,6 +18,7 @@
 #endif
 
 #include <imgui.h>
+#include <misc/freetype/imgui_freetype.h>
 
 namespace lava {
 
@@ -587,11 +588,15 @@ namespace lava {
     }
 
     bool imgui::upload_fonts(texture::ptr texture) {
+        auto& io = ImGui::GetIO();
+        if (!ImGuiFreeType::BuildFontAtlas(io.Fonts))
+            return false;
+
         uchar* pixels = nullptr;
 
         auto width = 0;
         auto height = 0;
-        ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
+        io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
 
         auto const font_format = VK_FORMAT_R8G8B8A8_UNORM;
         if (!texture->create(device, { width, height }, font_format))