An Introduction to Canvas in GNU Emacs
by Divya<br>2026 August 23<br>emacs canvas<br>Bad apple playing on the top right, a 2d rainbow growing box on the left. The bottom contains: dots 3d demo, pendulum, a bouncing ball.
The canvas patch has been finally merged to upstream GNU Emacs. If you have been following my Mastodon, this was a journey that took us ~8 months. But finally we have, in core Emacs, a feature that I desperately desired in early 2025 when I was starting the Emacs Reader project: a way to update and manipulate images in Emacs without choking Emacs by putting the image data in strings. I went through a series of different hacks to overcome these limitations, some more successful than others, but thanks to the magnificent Daniel (aka minad) who suggested the idea of exposing a pixel buffer from within Emacs via the dynamic module API. That idea is now a feature in Emacs, and will be part of Emacs 32 release cycle. A more detailed history about this will be written later, for now this article is an introduction to the new feature, its API and what you can do using it. I will try to keep it as self-contained as I can, so that beginners are able to understand it. But first, we need to clarify certain misconceptions that people might have about this feature.
1. Frequently Asked Questions
“Is this related to HTML5 Canvas?”
No. It has nothing to do with any web framework or technology. We call it “canvas” because it allows the user to draw arbitrarily on to a surface in an Emacs buffer. So at a high-level, both the HTML5 and Emacs canvas do the same thing, but they have zero relation in their implementation or how they work. HTML5 Canvas also has a more rich API with drawing functions and such, right now Emacs’ canvas API integrates with the existing image API and just provides access to the underlying pixel buffer via dynamic module API. See Canvas via Dynamic Modules.
“How is this different from SVG that Emacs has support for since a long time?”
Good question! So, at the level of an Emacs buffer the canvas looks and behaves just like any other Emacs image, including SVGs. Where it differs from SVG and other images is:
a canvas’ :data is just ARGB32 pixel data (in strings or vectors), so no specific compressed format.
the ability to access an Emacs Lisp image object from a lower level and be able to manipulate it
update the image without having to call a full redisplay
“Isn’t this still limited by Emacs’ redisplay engine?”
Not entirely. We have a function called canvas-refresh that is to be called every time you wish to update the canvas, and this function doesn’t use/call Emacs’ redisplay, it has its own redrawing path that only updates the specific glyphs in the buffer that pertain to that canvas. Thus, whereas a full redisplay would cost more because it will try to update all the glyphs that changed, canvas-refresh only updates what needs to be. Since Emacs 25 we have double-buffering so if that’s enabled in the frame you’d still need to call redisplay to flip the buffers, but that won’t slow down your canvas. If you’re not convinced, see the demos below that run smooth at 25, 30, and 60FPS without causing any lag to the rest of the Emacs session. Or, look at this where I display a 2K60 FPS and a 720p 30FPS video side by side without Emacs missing a beat!
“Is this hardware-accelerated? If not, why are you not using the GPU for this?”
Because we simply don’t need it :D! A canvas simply exposes a pixel buffer, and Emacs simply redisplays it as it changes. You can get your pixels hardware accelerated outside of Emacs if you wish to, and then put them in canvas’ pixel buffer. This will give you hardware acceleration where you need it the most, pixel calculation, texture math, etc. Ideally, an introduction of a GPU powered redisplay within Emacs itself would be great and certainly help but one can still reap much of the benefits of HW acceleration from current Emacs via canvas.
2. What Is a Canvas?
Before answering that question, we should ask: “what is an image in GNU Emacs?” Everybody has seen Emacs display dazzling images since decades, and of varying formats. How does Emacs do that? Well, at the level of an Emacs buffer we have something called Text Properties (also see Overlay Properties), as its name suggests it is a property list (aka plist) for a character position or a string within a buffer. Among the many properties a text can have, there’s a special one called the display property. This special property is responsible for how the text gets displayed. This is exactly what we use to display images! You use create-image to create an image object, which is exactly a plist, and then you set this image object (called an image specification) to be the display property of some text or overlay (which are like text properties but without the "text", it’s an object that belongs to a particular buffer with specific beginning and end and along with properties just like for usual text).
This...