Short answer
Serena asks a language server, so its references are type-resolved and it can edit and refactor at the symbol level, which Pixel does not. It runs as an MCP server beside a language server per language. Pixel is one binary with one index for every language it parses, scopes a whole task across files, and adds your Git history.
Side by side
Not benchmarked. No figure: how Pixel and Serena work, side by side. Nothing on this page is a measurement.
| Measure | Pixel | Serena |
|---|---|---|
| Callers and references | From a syntax graph, marked when incomplete | Type-resolved by the language server |
| Edits and refactors symbols | Renames only, with pixel rename | Yes: replace a body, insert, rename, safe delete |
| Scopes a task across files | Yes, pixel scope-task | No |
| Git history | Yes, with guarded Git writes | None documented |
| Runs as | One binary | An MCP server and a language server per language |
Where Serena wins
Type-resolved references, and symbol-level editing and refactoring through the language server.
How they differ
Serena drives a language server per language (or its JetBrains plugin) and exposes it as MCP tools: find a symbol, its references, replace its body, insert beside it, rename it. Its answers are as exact as the language server’s. Pixel parses every language it knows into one tree-sitter graph and a search index in .pixel/, and answers from the shell: pixel who-calls, pixel impact, pixel scope-task, with Git history through pixel dig-history or pixel file-history.
Choosing
Use Serena when the agent must edit or refactor at the symbol level with a compiler’s precision. Use Pixel to scope a task, measure a change’s blast radius and read the history behind it without starting a server per language. They combine: nothing stops an agent from asking Pixel where to look and Serena how to edit.