Redstart
the sexiest language for authoring The Graph subgraphs

Write the subgraph once.
Properly.

The most performant and secure language for authoring The Graph subgraphs. One typed source for schema, manifest, and mappings — compiled to AssemblyScript that's faster and safer than any human would hand-write. If it compiles, it works.

$curl -fsSL redstart-lang.com/install.sh | sh

The pitch

Would you rather write & maintain this —

Redstart1 file · drift impossible
token.red
abi ERC20 from "./abis/ERC20.json"

entity Account {
  id: Id<Bytes>
  balance: BigInt
}

entity Transfer immutable {
  id: Id<Bytes>
  from: Account
  to: Account
  value: BigInt
  timestamp: BigInt
}

source Token {
  abi: ERC20
  network: mainnet
  address: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
  startBlock: 6082465
}

handler on Token.Transfer(event) {
  let sender = Account.loadOrCreate(event.params.from, { balance: BigInt.zero })
  let receiver = Account.loadOrCreate(event.params.to, { balance: BigInt.zero })

  sender.balance = sender.balance - event.params.value
  receiver.balance = receiver.balance + event.params.value
  // dirty-tracked, auto-saved — forgetting .save() can't happen

  Transfer.create(event.id, {
    from: event.params.from,
    to: event.params.to,
    value: event.params.value,
    timestamp: event.block.timestamp,
  })
}
…or these three, kept in sync by hand?3 files · names must agree
import { BigInt } from "@graphprotocol/graph-ts";
import {
  Transfer as TransferEvent,
} from "../generated/Token/ERC20";
import { Account, Transfer } from "../generated/schema";

export function handleTransfer(event: TransferEvent): void {
  let sender = Account.load(event.params.from);
  if (sender == null) {
    sender = new Account(event.params.from);
    sender.balance = BigInt.zero();
  }

  let receiver = Account.load(event.params.to);
  if (receiver == null) {
    receiver = new Account(event.params.to);
    receiver.balance = BigInt.zero();
  }

  sender.balance = sender.balance.minus(event.params.value);
  receiver.balance = receiver.balance.plus(event.params.value);
  sender.save();      // forget this and balances silently desync
  receiver.save();

  let transfer = new Transfer(
    event.transaction.hash.concatI32(event.logIndex.toI32())
  );
  transfer.from = event.params.from;
  transfer.to = event.params.to;
  transfer.value = event.params.value;
  transfer.timestamp = event.block.timestamp;
  transfer.save();
}

Both produce the same store. Only one of them can't drift, can't forget a .save(), and can't let a renamed event compile. The AssemblyScript on the right is the genuine hand-written reference from our conformance suite — not a strawman.

Unrepresentable by construction

A whole class of bugs you can't write.

Forgotten .save()

Entities are dirty-tracked and flushed at handler end. The most common subgraph bug isn't expressible.

Arithmetic on null

There is no null — only Option<T>. Maths on a maybe-absent value is a compile error, not a silent miscompile.

Reverted calls aborting

Contract calls return Result. You must match before touching the value, so a revert can't kill the handler.

Manifest / ABI drift

Event signatures are derived from the ABI by reference. Rename an event and it's a compile error.

Writing derived fields

@derivedFrom fields are read-only by construction. Assigning to one doesn't type-check.

== vs === inversion

One equality, lowered correctly every time. The classic AssemblyScript footgun is gone.

Non-determinism

Date.now() and Math.random() are a compile error — they diverge Proof-of-Indexing across indexers and get them slashed.

eth_call in a loop

A contract call inside a loop — the documented 'stuck at 3%' sync killer — is flagged before you deploy it.

No lock-in

The eject path is the whole bet.

redstart build emits the exact files a hand-written subgraph has — readable, idiomatic AssemblyScript and GraphQL that graph build compiles unmodified. Walk away whenever you like; you keep the generated code, and it keeps working.

And it's proven, not promised: deployed to a live graph-node against an independent hand-written reference, our lowered AssemblyScript store-diffed 0 differences across every entity and field — byte-identical indexing.

token.red
redstart build
schema.graphql
subgraph.yaml
src/mappings.ts
graph codegen · graph build
compiles unmodified → WASM

See the drift disappear.

The playground runs the real compiler in your browser. Type Redstart, watch the three files generate live.