Note: Neomacs is in active alpha development. Expect rough edges, breaking changes, and missing features. Contributions and bug reports are very welcome!
Emacs's display engine (~50,000 lines of C in xdisp.c) was designed for text terminals in the 1980s. Despite decades of patches, it fundamentally struggles with:
- Large images β rendering slows down significantly
- Video playback β not natively supported
- Modern animations β no smooth cursor movement, buffer transitions, or visual effects
- Web content β limited browser integration
- GPU utilization β everything runs on CPU while your GPU sits idle
Throw it all away and start fresh.
Neomacs is rewriting Emacs from the ground up in Rust β starting with the display engine and expanding to the core:
- GPU display engine β ~4,000 lines of Rust replacing ~50,000 lines of legacy C, powered by wgpu (Vulkan/Metal/DX12/OpenGL)
- Rewriting Emacs C core in Rust β incrementally replacing critical C subsystems with safe, modern Rust
- True multi-threaded Elisp β real concurrency for the Lisp machine, not just cooperative threading
- 10x Elisp performance β Rust-optimized Lisp machine to dramatically speed up Elisp execution
- Zero-copy DMA-BUF β efficient GPU texture sharing (Linux)
- Full Emacs compatibility β your config and packages still work
2026-02-07_16-49-54.mp4
GPU-decoded directly β no CPU cost, won't block Emacs main thread.
GPU backend, DMA-BUF zero-copy.
GPU-backed terminal emulator embedded in Emacs buffer.
DMA-BUF zero-copy, GPU backend β no CPU cost.
2026-02-07_16-36-47.mp4
| Feature | Description |
|---|---|
| GPU Text Rendering | Hardware-accelerated text via wgpu (Vulkan/Metal/DX12/OpenGL) |
| Video Playback | GStreamer + VA-API hardware decode with DMA-BUF zero-copy |
| Cursor Animations | 8 modes with 7 movement styles and configurable spring trail |
| Scroll Animations | 21 scroll effects with 5 easing functions |
| Buffer Transitions | 10 buffer-switch effects (crossfade, slide, page-curl, etc.) |
| DMA-BUF Zero-Copy | GPU-to-GPU texture sharing via Vulkan HAL (no CPU readback) |
| Inline Images | GPU-accelerated image rendering in buffers |
| Inline WebKit | WPE WebKit browser views embedded in buffers |
All animations run on the GPU render thread at display refresh rate, independent of Emacs redisplay. Configure everything from Elisp.
8 particle/visual modes (Neovide-inspired):
| Mode | Description |
|---|---|
none |
No animation, instant movement |
smooth |
Smooth interpolated movement (default) |
railgun |
Particles shoot backward from cursor |
torpedo |
Comet-like trail follows cursor |
pixiedust |
Sparkly particles scatter around cursor |
sonicboom |
Shockwave ring expands from cursor |
ripple |
Concentric rings emanate outward |
wireframe |
Animated outline glow |
7 movement styles controlling how the cursor interpolates between positions:
| Style | Description |
|---|---|
exponential |
Smooth deceleration, no fixed duration (uses speed param) |
spring |
Critically-damped spring, Neovide-like feel (default) |
ease-out-quad |
Gentle deceleration curve |
ease-out-cubic |
Stronger deceleration curve |
ease-out-expo |
Sharp deceleration curve |
ease-in-out-cubic |
Smooth S-curve |
linear |
Constant speed |
The spring style also supports a 4-corner trail effect where leading corners snap ahead and trailing corners stretch behind, controlled by a trail-size parameter (0.0-1.0).
10 buffer-switch effects triggered when the visible buffer changes:
| Effect | Description |
|---|---|
none |
Instant switch |
crossfade |
Alpha blend between old and new (default) |
slide-left/right/up/down |
Directional slide transitions |
scale-fade |
Scale and fade |
push |
New buffer pushes old buffer out |
blur |
Blur transition |
page-curl |
3D page-turning effect |
21 scroll animation effects organized into categories:
| # | Effect | Category | Description |
|---|---|---|---|
| 0 | slide |
2D | Content slides in scroll direction (default) |
| 1 | crossfade |
2D | Alpha blend between old and new positions |
| 2 | scale-zoom |
2D | Destination zooms from 95% to 100% |
| 3 | fade-edges |
2D | Lines fade at viewport edges |
| 4 | cascade |
2D | Lines drop in with stagger delay |
| 5 | parallax |
2D | Layers scroll at different speeds |
| 6 | tilt |
3D | Subtle 3D perspective tilt |
| 7 | page-curl |
3D | Page turning effect |
| 8 | card-flip |
3D | Card flips around X-axis |
| 9 | cylinder-roll |
3D | Content wraps around cylinder |
| 10 | wobbly |
Deformation | Jelly-like deformation |
| 11 | wave |
Deformation | Sine-wave distortion |
| 12 | per-line-spring |
Deformation | Each line springs independently |
| 13 | liquid |
Deformation | Noise-based fluid distortion |
| 14 | motion-blur |
Post-process | Vertical blur during scroll |
| 15 | chromatic-aberration |
Post-process | RGB channel separation |
| 16 | ghost-trails |
Post-process | Semi-transparent afterimages |
| 17 | color-temperature |
Post-process | Warm/cool tint by direction |
| 18 | crt-scanlines |
Post-process | Retro scanline overlay |
| 19 | depth-of-field |
Post-process | Center sharp, edges dim |
| 20 | typewriter-reveal |
Creative | Lines appear left-to-right |
5 scroll easing functions:
| # | Easing | Description |
|---|---|---|
| 0 | ease-out-quad |
Standard deceleration (default) |
| 1 | ease-out-cubic |
Stronger deceleration |
| 2 | spring |
Critically damped spring with overshoot |
| 3 | linear |
Constant speed |
| 4 | ease-in-out-cubic |
Smooth S-curve |
;; All-in-one configuration:
;; (neomacs-set-animation-config
;; CURSOR-ENABLED CURSOR-SPEED CURSOR-STYLE CURSOR-DURATION
;; CROSSFADE-ENABLED CROSSFADE-DURATION
;; SCROLL-ENABLED SCROLL-DURATION
;; &optional SCROLL-EFFECT SCROLL-EASING TRAIL-SIZE)
;; Example: spring cursor, crossfade buffer switch, page-curl scroll with spring easing
(neomacs-set-animation-config t 15.0 'spring 150 t 200 t 150 7 2 0.7)
;; Example: fast linear cursor, no crossfade, wobbly scroll
(neomacs-set-animation-config t 20.0 'linear 100 nil 200 t 200 10 0 0.0)Neomacs aims to transform Emacs from a text editor into a modern graphical computing environment, while rewriting its internals in Rust:
- Rich media β 4K video, PDF rendering, image manipulation directly in buffers
- GPU-native β hardware-accelerated rendering, shader effects, 120fps animations
- GPU terminal β Rust-based terminal emulator replacing slow
term.el/ansi-term/vterm - Cross-platform β Linux (Vulkan), macOS (Metal), Windows (Vulkan/DX12)
- Rust core β rewrite Emacs C internals in Rust for memory safety and performance
- Multi-threaded Elisp β true concurrency for the Lisp machine, enabling parallel Elisp execution
- 10x faster Elisp β Rust-optimized Lisp interpreter/compiler to dramatically speed up Elisp
The goal: Make Emacs the most powerful and beautiful computing environment on any platform.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Emacs Core (C/Lisp) β
β neomacsterm.c ββββ neomacs_display.h (C FFI) ββββ neomacs-win.el β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β C FFI (ffi.rs)
ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β Rust Display Engine (neomacs-display) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Render Thread β β
β β render_thread.rs β winit event loop, frame dispatch β β
β β thread_comm.rs β command/event channels β β
β ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββ βββββββββββββΌβββββββββββ βββββββββββββββββββ β
β β Core β β wgpu Backend β β Media Backends β β
β β β β β β β β
β β scene β β renderer (145KB) β β video_cache β β
β β animation β β glyph_atlas β β GStreamer β β
β β cursor β β image_cache β β VA-API β β
β β scroll β β vulkan_dmabuf β β DMA-BUF β β
β β buffer β β 4 WGSL shaders β β β β
β β transitionβ β β β webkit_cache β β
β β faces β β cosmic-text β β WPE WebKit β β
β β grid β β text shaping β β β β
β βββββββββββββ ββββββββββββ¬ββββββββββββ βββββββββββββββββββ β
β β β
β ββββββββββββΌββββββββββββ β
β β winit (Windowing) β β
β ββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββΌβββββββββββββ
βΌ βΌ βΌ
βββββββββββ βββββββββββ βββββββββββ
β Vulkan β β Metal β βDX12/GL β
β (Linux) β β (macOS) β β(Windows)β
βββββββββββ βββββββββββ βββββββββββ
- Memory safety without garbage collection
- Zero-cost abstractions for high-performance rendering
- Excellent FFI with C (Emacs core)
- Modern tooling (Cargo, async, traits)
- Growing ecosystem for graphics (wgpu, winit, cosmic-text)
- Cross-platform β single API for Vulkan, Metal, DX12, and OpenGL
- Safe Rust API β no unsafe Vulkan/Metal code in application
- WebGPU standard β future-proof API design
- Active development β used by Firefox, Bevy, and many others
- Emacs source (this is a fork)
- Rust (stable, 1.92+)
- GStreamer (for video playback)
- VA-API (optional, for hardware video decode on Linux)
# Install dependencies
sudo pacman -S --needed \
base-devel autoconf automake texinfo clang git pkg-config \
gtk4 glib2 cairo \
gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad \
wpewebkit wpebackend-fdo \
wayland wayland-protocols \
mesa libva \
libjpeg-turbo libtiff giflib libpng librsvg libwebp \
ncurses gnutls libxml2 sqlite jansson tree-sitter \
gmp acl libxpm \
libgccjit
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build the Rust display engine
cargo build --release --manifest-path rust/neomacs-display/Cargo.toml
# Build Emacs
./autogen.sh
./configure --with-neomacs
make -j$(nproc)Note: WPE WebKit (
wpewebkit) is required for browser embedding. It is available in Arch Linux repos and via NixOS. On distros without WPE WebKit packages, the build will skip webkit support and build the Rust crate with--no-default-features --features "winit-backend,video".
docker build -t neomacs-build-test .Uses Arch Linux. See the Dockerfile for the full build environment.
Neomacs uses nix-wpe-webkit for the WPE WebKit dependency. Pre-built binaries are available via Cachix (~60MB download instead of ~1 hour build).
The flake.nix includes nixConfig for the Cachix cache. Pass --accept-flake-config to use it automatically, or configure it system-wide:
NixOS β add to your configuration (e.g., /etc/nixos/configuration.nix):
{
nix.settings.substituters = [ "https://nix-wpe-webkit.cachix.org" ];
nix.settings.trusted-public-keys = [ "nix-wpe-webkit.cachix.org-1:ItCjHkz1Y5QcwqI9cTGNWHzcox4EqcXqKvOygxpwYHE=" ];
}Non-NixOS β add to ~/.config/nix/nix.conf:
extra-substituters = https://nix-wpe-webkit.cachix.org
extra-trusted-public-keys = nix-wpe-webkit.cachix.org-1:ItCjHkz1Y5QcwqI9cTGNWHzcox4EqcXqKvOygxpwYHE=
Option 1 β Trust the nixConfig in flake.nix (simplest):
nix build --accept-flake-config
# Or enter development shell
nix develop --accept-flake-configOption 2 β Pass Cachix flags directly:
nix build \
--extra-substituters "https://nix-wpe-webkit.cachix.org" \
--extra-trusted-public-keys "nix-wpe-webkit.cachix.org-1:ItCjHkz1Y5QcwqI9cTGNWHzcox4EqcXqKvOygxpwYHE="Note: Both options require your user to be in
trusted-usersin/etc/nix/nix.conf(e.g.,trusted-users = root @wheel your-username), or configure the cache system-wide as shown above.
Legacy (non-flake users):
nix-shellcargo build --release --manifest-path rust/neomacs-display/Cargo.toml
./autogen.sh
./configure --with-neomacs
make -j$(nproc)neomacs/
βββ rust/neomacs-display/ # Rust display engine crate
β βββ src/
β β βββ lib.rs # Crate root
β β βββ ffi.rs # C FFI layer (~109KB)
β β βββ render_thread.rs # winit event loop + frame dispatch (~79KB)
β β βββ thread_comm.rs # Command/event channel types
β β βββ core/ # Engine core types
β β β βββ scene.rs # Scene graph
β β β βββ animation.rs # Base animation primitives
β β β βββ cursor_animation.rs # 8 cursor particle modes
β β β βββ scroll_animation.rs # 21 scroll effects + physics
β β β βββ buffer_transition.rs # 10 buffer-switch effects
β β β βββ animation_config.rs # Unified config system
β β β βββ frame_glyphs.rs # Glyph buffer from Emacs
β β β βββ face.rs # Face/style handling
β β β βββ glyph.rs # Glyph types
β β β βββ grid.rs # Character grid
β β β βββ types.rs # Color, Rect, CursorAnimStyle
β β βββ backend/
β β βββ wgpu/ # GPU renderer (primary backend)
β β β βββ renderer.rs # Main render pipeline (~145KB)
β β β βββ glyph_atlas.rs # cosmic-text glyph cache
β β β βββ image_cache.rs # Image texture management
β β β βββ video_cache.rs # GStreamer video pipeline
β β β βββ vulkan_dmabuf.rs # DMA-BUF zero-copy import
β β β βββ shaders/ # WGSL shaders (glyph, image, rect, texture)
β β βββ webkit/ # WPE WebKit browser embedding
β β βββ wpe/ # WPE backend support
β β βββ tty/ # Terminal backend
β βββ include/
β β βββ neomacs_display.h # Generated C header
β βββ Cargo.toml
βββ src/ # Emacs C source
β βββ neomacsterm.c # Terminal hooks + Lisp DEFUNs (~156KB)
β βββ neomacsfns.c # Frame/font functions (~60KB)
β βββ neomacs_display.h # C header (local copy)
βββ lisp/term/neomacs-win.el # Lisp initialization + animation config
βββ doc/display-engine/ # Design documentation
Contributions welcome! Areas where help is needed:
- Graphics programmers β shader effects, rendering optimizations
- Rust developers β architecture, performance, safety
- Emacs hackers β Lisp API design, integration testing
- Documentation β tutorials, API docs, examples
See doc/display-engine/DESIGN.md for architecture details.
Built with:
- wgpu β Cross-platform GPU rendering (Vulkan/Metal/DX12/GL)
- winit β Cross-platform window management
- cosmic-text β Pure Rust text shaping
- GStreamer β Video playback with VA-API
- ash β Vulkan bindings for DMA-BUF import
- Inspired by Neovide cursor animations
GNU General Public License v3.0 (same as Emacs)
