# GRC-003: Rust Subgraph Mappings - A Native Rust ABI for graph-node

**URL:** https://forum.thegraph.com/t/grc-003-rust-subgraph-mappings-a-native-rust-abi-for-graph-node/6889
**Category:** Graph Request for Comment (GRC)
**Created:** [April 3, 2026, 10:30am UTC](https://forum.thegraph.com/t/grc-003-rust-subgraph-mappings-a-native-rust-abi-for-graph-node/6889 "2026-04-03T10:30:04Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![AxiomaticAardvark](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/axiomaticaardvark/32/2882_2.png) [@AxiomaticAardvark](https://forum.thegraph.com/u/AxiomaticAardvark)
#### Post date: [April 3, 2026, 10:30am UTC](https://forum.thegraph.com/t/grc-003-rust-subgraph-mappings-a-native-rust-abi-for-graph-node/6889/1 "2026-04-03T10:30:04Z")

</div>

Stage: GRC/FRC  
Authors: [cargopete (Petko Pavlovski) · GitHub](https://github.com/cargopete)  
Related: [Add Rust ABI support for WASM subgraphs by cargopete · Pull Request #6462 · graphprotocol/graph-node · GitHub](https://github.com/graphprotocol/graph-node/pull/6462) ·

> **[GitHub - cargopete/graphite: A Rust SDK for building subgraphs on The Graph](https://github.com/cargopete/graphite)**
>
> A Rust SDK for building subgraphs on The Graph

**Summary**  
This GRC proposes adding first-class Rust support to graph-node as a second mapping language alongside AssemblyScript. Subgraph developers write handlers in Rust, compile to wasm32-unknown-unknown, and declare language: wasm/rust in their manifest. Graph-node dispatches to a new rust\_abi serialization layer; the existing HostExports layer is unchanged.

A working implementation exists: the Graphite SDK compiles ERC20 handlers to WASM, and the graph-node fork has been live-tested indexing real USDC Transfer events from Ethereum mainnet via GraphQL.

**Motivation**  
AssemblyScript’s pain points are well-documented in the community, but they are structural — not fixable at the SDK layer.

Nullable handling crashes at runtime. AS type narrowing only works on local variables. Accessing a nullable property directly compiles without error but produces a WASM trap at runtime. Rust’s Option eliminates this entire class of bug at compile time.

No closures, no functional programming. array.map(), .filter(), and .forEach() all crash the AS compiler. Rust’s iterator chains are transformational for handler code.

Hostile debugging. When the AS compiler crashes, the official guidance is to “comment the whole file and uncomment it little by little.” Rust’s compiler gives actionable errors pointing directly to the problem.

Additional issues: no Date support, no regex, === performs identity not value comparison, Matchstick requires PostgreSQL and produces silent type-mismatch failures.

The Graph has already validated this path. Substreams uses Rust compiled to WASM for high-performance indexing. This proposal extends that foundation to the subgraph layer.

**Design**  
HostExports is already fully language-agnostic — it operates on native Rust types (String, HashMap\<String, Value\>, Vec). The AS coupling lives entirely in runtime/wasm/src/asc\_abi/. Adding Rust support means a parallel rust\_abi/ module and dispatching on language: in the manifest.

Graph-node calls Rust handlers with a simple C calling convention:  
extern “C” fn handle\_transfer(event\_ptr: u32, event\_len: u32) → u32;

Serialization uses a simple TLV (Type-Length-Value) format. The module owns a bump allocator; graph-node writes serialized event data in, calls the handler, then calls reset\_arena(). No managed heap, no graph-node reaching into AS-style TypedMaps.

What we tried to learn from the ASC ABI:

- No managed heap — bump allocator owned by the module, arena reset after each handler
- Explicit TLV format with a fixed, documented value tag table — no implicit type coercions, endianness specified in the protocol
- Language detection via manifest (language: wasm/rust) — clean dispatch, no heuristics
- Versioned from day one — apiVersion: 0.0.1 gives an explicit migration path

**Developer experience**  
A Rust ERC20 handler:

use graphite::prelude::\*;

#[handler]  
pub fn handle\_transfer(event: TransferEvent) {  
let mut transfer = Transfer::new(&format!(“{}-{}”,  
event.tx\_hash, event.log\_index));  
transfer.from = event.from;  
transfer.to = event.to;  
transfer.value = event.value.clone();  
transfer.save();  
}

Testing runs natively with cargo test — no WASM compilation, no PostgreSQL:

#[test]  
fn transfer\_creates\_entity() {  
let mut host = MockHost::default();  
handle\_transfer(&mut host, &mock\_event());  
assert\_eq!(host.store.entity\_count(“Transfer”), 1);  
}

Implementation status  
This is not a design-only proposal. A complete implementation  
exists and has been live-tested.

graph-node fork (cargopete/graph-node, branch rust-abi-support):

- rust\_abi/ module (~1,450 LOC): types, entity serialization,  
trigger serialization, host function wrappers
- Manifest parsing and language dispatch
- Rust handler invocation with arena reset
- Wasmtime fuel metering (10B instruction budget, OutOfFuel as a  
deterministic error)
- All existing tests passing

Graphite SDK (cargopete/graphite):

- #[derive(Entity)] and #[handler] proc macros
- TLV deserializer, ABI + schema codegen, full CLI
- MockHost for native unit testing, no external dependencies

Live test: deployed ERC20 subgraph to the graph-node fork, indexed real USDC Transfer events from Ethereum mainnet (block 24756400+), queried via GraphQL. All fields correct.

Draft PR: [Add Rust ABI support for WASM subgraphs by cargopete · Pull Request #6462 · graphprotocol/graph-node · GitHub](https://github.com/graphprotocol/graph-node/pull/6462)

**Scope of graph-node changes**  
The change is fully additive — existing AS subgraphs are unaffected. New code lives in rust\_abi/ (~1,450 LOC across 5 files). Modified files: manifest parsing, linker dispatch, handler  
invocation, Ethereum trigger serialization. HostExports is unchanged. Adding a new host function requires one thin ptr+len wrapper in rust\_abi/host.rs — no changes to the AS path.

Open questions for community feedback

1. Namespace. Host functions currently use “graphite” as the WASM import namespace. Should this be “graph” or something more official?
2. API versioning. Should apiVersion: 0.0.1 be independent of the AS versioning scheme, or aligned with it?
3. Shared constants. TLV value tags are duplicated between graph-node and the SDK. Worth a shared graph-abi crate, or is a spec doc sufficient?
4. Chain coverage. Ethereum triggers are fully serialized. NEAR is stubbed. Proposed scope for initial merge: Ethereum-only.
5. ABI evolution. If the TLV format needs to change, apiVersion in the manifest is the current migration story — is that sufficient?

References

- [Add Rust ABI support for WASM subgraphs by cargopete · Pull Request #6462 · graphprotocol/graph-node · GitHub](https://github.com/graphprotocol/graph-node/pull/6462)
- [GitHub - cargopete/graphite: A Rust SDK for building subgraphs on The Graph · GitHub](https://github.com/cargopete/graphite)
- [https://github.com/cargopete/graphite/blob/main/rfc-rust-subgraph](https://github.com/cargopete/graphite/blob/main/rfc-rust-subgraph)  
.md
- [Substreams Quick Start | Docs | The Graph](https://thegraph.com/docs/en/substreams/) — prior art for  
Rust→WASM in The Graph ecosystem

---

<div class="post-metadata">

### Author: ![AxiomaticAardvark](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/axiomaticaardvark/32/2882_2.png) [@AxiomaticAardvark](https://forum.thegraph.com/u/AxiomaticAardvark)
#### Post date: [April 9, 2026, 6:37am UTC](https://forum.thegraph.com/t/grc-003-rust-subgraph-mappings-a-native-rust-abi-for-graph-node/6889/2 "2026-04-09T06:37:44Z")

</div>

After the feedback on the [graph-node PR](https://github.com/graphprotocol/graph-node/pull/6462) - specifically the maintenance concern around a second ABI (and the general reluctance of the graph-node maintainers to accept outside contributions), I’ve been thinking about whether there’s a way to deliver the same developer experience (better, even) without touching graph-node at all. There is, and I’m going to build it, stay tuned.

---

<div class="post-metadata">

### Author: ![AxiomaticAardvark](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.thegraph.com/axiomaticaardvark/32/2882_2.png) [@AxiomaticAardvark](https://forum.thegraph.com/u/AxiomaticAardvark)
#### Post date: [April 9, 2026, 3:45pm UTC](https://forum.thegraph.com/t/grc-003-rust-subgraph-mappings-a-native-rust-abi-for-graph-node/6889/3 "2026-04-09T15:45:38Z")

</div>


