Library / SDK
embedded-graphics/embedded-graphics avatar
embedded-graphics/embedded-graphics

embedded-graphics for no_std embedded displays

A no_std graphics library for embedded applications

1,346 stars134 forksRustApache-2.0

At a glance

What is it?
embedded-graphics is a Rust 2D graphics library for memory constrained devices that renders pixels through iterators without requiring a display buffer. It suits firmware developers who need primitives, text, images, and a common DrawTarget API across external display drivers.
Who is it for?
Adopt embedded-graphics when the target must render 2D graphics without a framebuffer or dynamic allocator, and the display ecosystem has a compatible DrawTarget implementation. Do not choose it as a self-contained display driver or a buffered desktop graphics stack.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 27 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why embedded-graphics targets small displays

embedded-graphics addresses a specific constraint in embedded firmware: rendering can require more RAM than the device can spare. The project describes itself as a 2D graphics library focused on memory constrained embedded devices. Its central design goal is to draw without buffers. The crate is compatible with `no_std`, does not require a dynamic memory allocator, and does not require pre-allocating large memory regions. That makes it relevant to small screens, electronic paper, memory LCDs, OLED modules, and other hardware where a full framebuffer may be impractical. The library is aimed at Rust developers writing firmware or device-side rendering code, not at applications that expect a conventional desktop graphics API. It supplies drawing items and a shared rendering interface, while hardware-specific display support remains outside the core repository.

Iterator-based rendering without a framebuffer

The defining mechanism is iterator-based drawing. Pixel colors and positions are calculated as drawing progresses, with only a minimum of saved state. Instead of constructing a complete image in memory and then transferring it to a display, the application can let the library produce drawable pixels or drawing commands through the `DrawTarget` API. This changes the memory profile of rendering: the application can spend less RAM because it does not need to store every rendered pixel at once. The README says this can reduce RAM use at little to no performance cost, but it does not provide a universal performance guarantee. Actual behavior depends on the drawing operation, target implementation, compiler, and device. The design is also a trade-off. Repeated computation and transfer can matter on some targets, while retaining a framebuffer may make later updates or compositing more convenient. `embedded-graphics-core` supplies the core interfaces, and external crates implement support for particular displays.

Built-in primitives, text, images, and fonts

The repository includes built-in items for raw data images, lines, rectangles, circles, ellipses, arcs, sectors, triangles, polylines, and rounded rectangles. It also includes text and monospaced font support. This gives a firmware project a common vocabulary for basic interface elements without requiring a separate graphics engine for each primitive. The library is extensible. The README names external crates for BMP, TGA, and QOI images, proportional bitmap fonts, TTF and OTF font support, layout, text boxes, plotting, canvas drawing, framebuffer-backed drawing, alpha compositing, color translation, and Unicode fonts. Those crates are not bundled with the main library, so their availability and compatibility must be checked separately. The README specifically says that some listed crates may not support the latest version of embedded-graphics. This matters when selecting a font or image format: the high-level concept may be available, but the relevant extension crate can introduce a version constraint.

DrawTarget separates rendering from hardware drivers

embedded-graphics does not include display drivers directly. The repository layout and README point to the `DrawTarget` API in `embedded-graphics-core`, which external crates implement for physical displays. The listed examples include `epd-waveshare` for Waveshare ePaper displays, `hub75` for RGB matrix displays, `ili9341` for TFT LCD panels, `sh1106` and `sh1108` for OLED displays, and `oled-async` for asynchronous OLED drivers. A browser simulator is also listed for development, and `embedded-canvas` is listed for drawing into an intermediate canvas. This separation keeps the main crate focused on graphics operations, but it means installation of embedded-graphics alone does not make a physical display usable. A driver must match the hardware, communication method, color model, and version of the core API. The README also warns that some drivers may not support the latest embedded-graphics version. Reviewing the driver's own documentation is therefore part of evaluating this project, not an optional integration detail.

Installing and first use through the documented workspace checks

After adding the package to an application, the first concrete step is to implement or select a `DrawTarget`, then use the primitive and text APIs against that target. The README names the APIs and capabilities but does not include a complete drawable example, target configuration, or hardware wiring sequence. For that reason, a code example would require assumptions not supported by the repository documentation. The appropriate first verification is to run the documented tests, then compile for the exact embedded target used by the display driver.

When embedded-graphics is the wrong choice

The library is a poor fit when the application requires a complete buffered framebuffer, conventional window-system integration, or a ready-made display driver. Those needs conflict with the project's explicit bufferless direction and its exclusion of direct display drivers. It may also be the wrong abstraction when an external crate is incompatible with embedded-graphics, particularly for image decoding, advanced fonts, layout, or hardware support. A display driver with a different rendering model can require an adapter or another graphics approach. The choice of `fixed_point` and `nalgebra_support` features may also affect dependency and target compatibility. The README states that some external crates may not support the latest version, so compatibility is a practical boundary rather than a minor packaging note. The repository does not document a rollback procedure for an upgrade, nor does it claim compatibility across every listed driver, font, or image crate.

Maintenance, licensing, and upgrade boundaries

The repository is not archived, and its last push was on 2026-09-26. The recorded releases include `embedded-graphics-v0.8.2` on 2026-02-15, `embedded-graphics-v0.8.1` on 2023-08-10, and `embedded-graphics-v0.8.0` on 2023-05-14. The package metadata declares version `0.8.1`, while the repository's release history includes `0.8.2`, so an application should confirm the version resolved from crates.io or the intended dependency source. The crate is licensed under `MIT OR Apache-2.0`, and the repository contains `LICENSE-APACHE` and `LICENSE-MIT`. The README notes that some external crates may not support the latest embedded-graphics version. Upgrading therefore requires checking the core crate, `embedded-graphics-core`, the display driver, fonts, image formats, and any feature-dependent code together. The documentation does not give a migration policy beyond the repository's migration files for older version transitions.

Editorial conclusion

Adopt embedded-graphics when the target must render 2D graphics without a framebuffer or dynamic allocator, and the display ecosystem has a compatible DrawTarget implementation. Do not choose it as a self-contained display driver or a buffered desktop graphics stack. Verify first that the selected display driver, font crate, image format crate, Rust toolchain, and target triple support the version you intend to use, because the README explicitly warns that external crates may not support the latest embedded-graphics version.

Frequently asked questions

Does embedded-graphics require a framebuffer?

No. Its documented design goal is drawing without buffers, calculating pixel colors and positions on the fly through an iterator-based approach. A framebuffer-backed option exists through an external crate, but it is not required by the core design.

Does embedded-graphics include drivers for physical displays?

No. It provides the `DrawTarget` API, which external crates implement for particular displays. The README lists examples such as `epd-waveshare`, `hub75`, `ili9341`, `sh1106`, and `oled-async`.

Can embedded-graphics be used without a dynamic memory allocator?

Yes. The README states that the crate is `no_std` compatible and works without a dynamic memory allocator or large pre-allocated memory blocks.

What Rust version does the repository require?

The `Cargo.toml` declares `rust-version = "1.81"` and uses Rust edition `2021`.

Official sources

  1. embedded-graphics/embedded-graphics on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/embedded-graphics-embedded-graphics.svg)](https://hysenlabs.com/projects/embedded-graphics-embedded-graphics)

Was this useful?