Table of Contents
- Getting started
- What you can do today
- The three runtime modes
- 1. Nested winit backend
- 2. Headless backend
- 3. udev / tty backend
- First commands to know
- Validate a config
- Run headless
- Run nested
- Run nested and start one app immediately
- Run the TTY baseline on a spare VT
- Which example config should you start with?
- A very small mental model for config files
- What “Rust provides facts, Lua provides policy” means for you
- Good first edits for a new user
- Change the terminal bind
- Change the launcher bind
- Change the background clear color
- Make move behavior imperative instead of declarative
- Where to go next
Getting started
This page is for someone who wants to try evil, run a config, and understand the minimum things needed to begin.
What you can do today
The most practical starting points are:
- run
evilin a nested window with thewinitbackend - validate configs without starting the compositor
- run the headless backend for policy testing
- try the tty backend on a spare virtual terminal if you want to explore the prototype standalone path
The three runtime modes
1. Nested winit backend
This is the easiest live mode to start with. It runs the compositor in a normal window inside your existing desktop session.
Use it when you want to:
- try a config
- test hooks against real clients
- work on live behavior without switching away from your normal desktop
2. Headless backend
This does not create a live display. It is useful for:
- policy experiments
- runtime tests
- state dump / JSON inspection
3. udev / tty backend
This is the standalone backend. It is still more experimental and should be treated carefully.
Use it on a spare VT, not your current desktop session.
First commands to know
Validate a config
cargo run --bin evil -- --check-config --config examples/tty-baseline.lua
This is the safest first command. If the config is invalid, you will see a validation error without starting the compositor.
Run headless
cargo run --bin evil -- --backend headless --config examples/tty-baseline.lua
Run nested
cargo run --bin evil -- --backend winit --config examples/tty-baseline.lua
Run nested and start one app immediately
cargo run --bin evil -- --backend winit --config examples/tty-baseline.lua --command foot
Run the TTY baseline on a spare VT
scripts/start-tty.sh
Which example config should you start with?
| Goal | Example | File |
|---|---|---|
| TTY baseline | TTY baseline | examples/tty-baseline.lua |
| Tiling-style config | Tiling pages | examples/tiling.lua |
A very small mental model for config files
Most configs do these things:
- load helpers with
include(...) - call
evil.config({...}) - add key bindings with
evil.bind(...) - add startup commands with
evil.autostart(...) - set hooks like
evil.on.key = function(ctx) ... end
If you are new, do not worry about all of Lua at once. Learn just enough to:
- change a bind
- change a command
- change a hook
- copy a helper function and adjust it
What “Rust provides facts, Lua provides policy” means for you
As a user, the simple meaning is:
- Rust knows which windows and outputs exist
- Lua decides how your desktop should behave
So if you want to change:
- focus rules
- placement style
- movement style
- resize style
- page / workspace-like behavior
- compositor-drawn decorations
those are all good candidates for Lua config changes.
Good first edits for a new user
Try these first:
Change the terminal bind
evil.bind("Super+Return", "spawn", { command = "kitty" })
Change the launcher bind
evil.bind("Super+D", "spawn", { command = "fuzzel" })
Change the background clear color
draw = {
clear_color = { 0.05, 0.05, 0.08, 1.0 },
}
Make move behavior imperative instead of declarative
evil.on.move_update = function(ctx)
evil.window.move(ctx.window.id, ctx.window.x + ctx.dx, ctx.window.y + ctx.dy)
end
Where to go next
evil wiki
- Home
- Getting started
- Architecture and philosophy
- Configuration guide
- Writing your first config
- Lua basics for evil users
- Lua API guide
- Lua API cheat sheet
- Hooks guide
- Hook payload summary
- Queries, commands, and actions
- Drawing and visuals
- Example configs overview
- Example shared helpers and rules
- IPC protocol
- Testing and debugging
- Contributor validation matrix
- Feature status and limitations
- Feature and support matrix
- Recipes