TFT_eSPI: an Arduino display library configured by editing its own headers
Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
At a glance
- What is it?
- TFT_eSPI is a C graphics library for 32-bit boards that drives SPI and parallel TFT panels on RP2040, STM32, ESP8266 and ESP32. Its defining choice is that the panel and pins live inside the library, not in your sketch.
- Who is it for?
- Adopt TFT_eSPI when you have one known panel per board and want low-level control of the bus, DMA and fonts on RP2040, STM32, ESP8266 or ESP32. Do not adopt it if you need to switch panels at runtime, need touch or pixel reads while the RP2040 PIO SPI path is enabled, or want a retained-mode widget toolkit out of the box.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 179 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem TFT_eSPI solves on 32-bit boards
The generic Arduino graphics path pushes every pixel through slow virtual calls, and on a 240x320 panel that cost is visible. TFT_eSPI is written for 32-bit processors and is performance optimised for RP2040, STM32, ESP8266 and ESP32; other 32-bit chips still work but fall back to the slower generic Arduino interface calls. It targets people who are writing firmware, not people assembling a UI from a designer tool. The repository ships examples grouped by resolution (160 x 128, 320 x 240, 480 x 320) plus DMA test, Sprite, Smooth Fonts, Smooth Graphics, PNG Images, GUI Widgets, Test and diagnostics and ePaper folders, which tells you the intended audience: someone who wants sprites, anti-aliased arcs and compressed image blitting on a microcontroller. The GUI examples for sliders, buttons, graphs and meters live in a separate library, TFT_eWidget, so the core stays a drawing and text layer rather than an application framework.
Why configuration lives in User_Setup.h instead of your sketch
This is the design decision that shapes everything else. The README states plainly that the screen controller, interface pins and library configuration settings must be defined inside the library and cannot be defined in the Arduino sketch, and it points to User_Setup_Select.h. The repository layout confirms it: User_Setup.h, User_Setup_Select.h and a User_Setups directory sit at the top level, and the README describes the approach as keeping examples clean of long configuration options. The trade-off is real. You get short sketches and one place to change wiring. You lose per-project isolation, because two boards with different panels in the same Arduino installation share that header unless you use the selection mechanism or separate board packages. There is also a TFT_config.h and a Kconfig file at the top level, which suggests the configuration surface extends beyond the classic Arduino path, but the README does not document a Kconfig workflow, so treat that as unexplored ground rather than a supported route.
Install TFT_eSPI and get a first sketch running
The README says the library can be loaded using the Arduino IDE's Library Manager. After installation, the setup step is not optional: you must open User_Setup_Select.h and select or create a setup file that matches your display controller and pin wiring. The README references named setup files in the User_Setups folder, for example Setup70_ESP32_S2_ILI9341.h, Setup70b_ESP32_S3_ILI9341.h, Setup70c_ESP32_C3_ILI9341.h and Setup70d_ILI9488_S3_Parallel.h. Those filenames are the concrete evidence of how per-board configuration is distributed. Once the right setup is selected, the drawing calls themselves are the familiar Arduino shape. The README gives this example of setting text colour with background rendering enabled for smooth fonts, where the third parameter is the new true/false argument:
tft.setTextColor(TFT_WHITE, TFT_BLUE, true);
spr.setTextColor(TFT_BLUE, TFT_BLACK, true);The README notes this is a breaking change for some sketches because the background parameter is now required for that behaviour, and that the default is false when the parameter is missing. Existing code that relied on the old implicit behaviour will render differently until the parameter is added. If you are on ESP32, check your board package version first: the README states that support for the ESP32-S2, S3 and C3 means the library requires the ESP32 Arduino board package 2.x.x or later.
DMA, PIO and the limits that come with them
DMA is available with the ESP32, RP2040 and STM32 over SPI. DMA with a parallel interface, 8-bit or 16-bit, is only supported with the RP2040. The RP2040 8-bit parallel interface uses the PIO, and the README says the PIO now manages setWindow and block fill so the processor is free while areas are filled with colour. The same PIO can drive SPI if you put #define RP2040_PIO_SPI in the setup file, and the README states touch screens and pixel read operations are not supported when the PIO interface is used. That is a hard boundary, not a tuning knob: if your design reads pixels back or polls a touch controller, enabling the PIO SPI path removes those capabilities. The README also warns that the RP2040 PIO features only work with Earle Philhower's board package, not the Arduino Mbed version, and that PIO for SPI allows over-clocking the RP2040 up to 250MHz in that package while maintaining high SPI clock rates. On the ESP32 S3 side, the README says DMA capability now works with ESP-IDF versions greater than 2.0.14, tested with the Arduino 3.3.6 board package.
Smooth fonts, sprites and the RAM you will pay for them
Anti-aliased drawing and font rendering are where the library spends its complexity. The README describes new functions for smooth arcs, circles and rounded rectangle outlines, with the arc algorithm using an optimised fixed point sqrt() to help processors without a hardware floating point unit, naming the RP2040. Arcs can be drawn with or without anti-aliasing, and the non-anti-aliased path renders faster. For fonts, the README points to a separate compatible library, OpenFontRender by takkaO, which renders TrueType fonts to a screen or sprite with scalable anti-aliased glyphs and left, middle and right justified text. That route has a RAM floor: the README states the ESP8266 does not have sufficient RAM for the glyph render complexity, and it notes that the PNG image examples require roughly 40kbytes RAM. Smooth fonts rendered direct to the TFT now update line by line and block by block without drawing pixels twice, which the README presents as a way to reduce flicker on quickly changing values. The cost is that third text-colour parameter described earlier, which is a source-level break for existing sketches.
TFT_eSPI vs Adafruit GFX, LVGL and LovyanGFX
Adafruit GFX is the default Adafruit graphics core, and its portability comes from routing every operation through a hardware abstraction layer. That is why it runs on almost anything and why it is slower on the same panel: the abstraction is the cost. TFT_eSPI inverts that, optimising for four named processor families and accepting slower generic calls elsewhere. LVGL is a different kind of project: a retained-mode widget toolkit with its own object tree, whereas TFT_eSPI is immediate-mode drawing plus a sprite buffer, and the README keeps its own widgets in a separate TFT_eWidget library. If you want buttons and sliders with layout and event handling, LVGL is the closer fit and TFT_eSPI is a display driver underneath it. LovyanGFX is the nearest functional peer, a display library with its own configuration model; the difference a reader should weigh is that TFT_eSPI's configuration lives in library headers selected through User_Setup_Select.h, while the README does not describe any runtime panel switching in TFT_eSPI at all.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-04-03. The most recent release listed is V2.5.43 from 2024-03-06, described as bug fixes, preceded by V2.5.34 (ESP32 board package compatibility update) and v2.5.33 (minor bug fixes). So the pattern is small, targeted releases rather than a steady feature cadence, and the release notes themselves are terse. The README asks users to use the Discussions tab for Q&A and the Issues tab only for problems with the library, which is a practical signal about where to look when something breaks. On licensing, the repository carries a license.txt and the project metadata reports NOASSERTION, meaning the automated classifier could not map the file to a known SPDX identifier. That is not a statement about your rights; read license.txt yourself and, if you are shipping a product, have someone qualified confirm the terms. Upgrade cost is dominated by source-level breaks like the smooth-font background parameter, plus board package coupling: the README ties S2/C3/S3 support to ESP32 board package 2.x.x or later and the S3 DMA fix to ESP-IDF versions greater than 2.0.14, so an Arduino core upgrade can force a library upgrade with it.
Editorial conclusion
Adopt TFT_eSPI when you have one known panel per board and want low-level control of the bus, DMA and fonts on RP2040, STM32, ESP8266 or ESP32. Do not adopt it if you need to switch panels at runtime, need touch or pixel reads while the RP2040 PIO SPI path is enabled, or want a retained-mode widget toolkit out of the box. Before wiring anything, open User_Setup_Select.h and confirm which User_Setups file matches your controller and pin map, then verify that your ESP32 board package is 2.x.x or later, since the S2/C3/S3 support depends on it.
Frequently asked questions
How do I install TFT_eSPI?
The README says the library can be loaded using the Arduino IDE's Library Manager. After that you still have to select a setup file through User_Setup_Select.h, because the controller and pins are defined inside the library rather than in your sketch.
How do I use TFT_eSPI with an ESP32?
Pick the matching setup file for your ESP32 variant and panel, for example Setup70b_ESP32_S3_ILI9341.h or Setup70c_ESP32_C3_ILI9341.h, and make sure the ESP32 Arduino board package is 2.x.x or later. DMA is supported on the ESP32 S3, and the README notes it works with ESP-IDF versions greater than 2.0.14.
What is TFT_eSPI?
It is an Arduino IDE compatible graphics and fonts library for 32-bit processors, performance optimised for RP2040, STM32, ESP8266 and ESP32. It supports SPI and parallel TFT panels and can use DMA on the ESP32, RP2040 and STM32 over SPI.
How does TFT_eSPI compare with Adafruit GFX?
Adafruit GFX is portable across many boards because it goes through a hardware abstraction layer, while TFT_eSPI is optimised for four named processor families and uses slower generic Arduino calls on other 32-bit chips. The README also notes that TFT_eSPI configuration must live in the library, not in the sketch.
How do I use the TFT_eSPI library?
Install it through the Arduino Library Manager, then edit User_Setup_Select.h to point at a setup file matching your controller and pins. Drawing then happens through calls such as tft.setTextColor(TFT_WHITE, TFT_BLUE, true), where the third argument controls background rendering for smooth fonts.
How do I set up TFT_eSPI?
Setup means choosing the right file in the User_Setups folder through User_Setup_Select.h, since the README states pins and the controller cannot be defined in the sketch. The README lists files such as Setup70_ESP32_S2_ILI9341.h and Setup70d_ILI9488_S3_Parallel.h as examples of that per-board configuration.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bodmer-tft-espi)