Redstart
Stage 0 · public good for The Graph

Write the subgraph once.
Not three times.

A subgraph is three files held together by stringly-typed names. Redstart unifies schema, manifest, and mappings into one typed language — then transpiles to AssemblyScript the canonical toolchain compiles unmodified.

$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.

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.

That claim is continuously checked: a field-level store-diff against independently hand-written subgraphs is the project's stated kill/pivot gate.

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.