Once your dApp outgrows a single validator, the feedback loop gets painful. Write a validator, build a transaction, submit to a testnet, wait for confirmation, check the result, adjust. Every iteration costs time.
For JS/TS developers, it’s been even rougher. In particular, when you are building something non-trivial, multi-step protocols, time-dependent unlocks, transactions interactions or battery of scenarios - you’re either spinning up a local node or hitting a testnet.
We built the Scalus Emulator to fix that.
‘npm install scalus’ gives you a full in-memory Cardano ledger — native JS, no WASM, no infrastructure.
import { Emulator, SlotConfig } from "scalus";
const emulator = Emulator.withAddresses(
[aliceAddress, bobAddress],
SlotConfig.mainnet,
BigInt(50_000_000_000)
);
const result = emulator.submitTx(txCborBytes);
if (result.isSuccess) {
console.log(`tx confirmed: ${result.txHash}`);
} else {
console.error(result.error);
console.log(result.logs); // script execution traces
}
Submit transactions, advance slots, snapshot state, roll back.
Phase 1 (structure, signatures, fees, value conservation) and Phase 2 (Plutus script execution with cost tracking) — a complete scenario testing environment that runs as fast as your tests do.
What you get:
- Real validation — Phase 1 and Phase 2, Plutus V1/V2/V3
- Time travel — emulator.setSlot(1000) to test validity intervals and unlock conditions
- Snapshots — capture UTxO state, run a sequence, roll back
- Instant feedback — detailed errors with script trace logs, no waiting for blocks
Docs: JavaScript/TypeScript Emulator | Scalus Docs
If you’ve been building complex transaction flows in JS/TS, we’d love to hear how you’ve been handling testing — and whether this fills the gap.