Skip to content
Tech News
← Back to articles

Amber Tree: A Middle Ground Between Rowan Red and Green Trees

read original more articles

2026/06/04

¶Problems of rowan red tree and green tree

Rowan provides two kinds of syntax trees:

Red tree: Feature-rich and API-friendly. It allows traversal not just to children and tokens, but also to parents and siblings via parent references. However, these parent references create cyclic references, so nodes must be heap-allocated and wrapped in Rc to reduce cloning overhead.

to reduce cloning overhead. Green tree: Much better performance, but with trade-offs. You can only access children, and the API doesn’t directly distinguish between nodes and tokens - it returns NodeOrToken enum, which is awkward to work with. Green nodes also don’t store a text range, so there’s no way to know where a node appears in the source code.

It’s worth noting that in rowan, the red and green trees aren’t two independent structures. They are different views of the same underlying data: the red tree is essentially a wrapper around the green tree.

For most use cases in my project, wasm-language-tools, I don’t need to traverse up to parents or siblings. I use the red tree primarily because its API is more convenient and it provides text ranges. So can I design a syntax tree that offers a reasonably friendly API and text range support, without parent/sibling consideration, while approaching green tree performance?

Absolutely. And it turns out to be much simpler than you might expect. Since its capabilities sit somewhere between the red and green trees, I call it the “Amber Tree.”

Here’s the definition of an amber node:

#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct AmberNode < 'a > { green : & 'a GreenNode , range : TextRange , }

... continue reading