ethers.js vs. viem 2026: was sich bei Wahl oder Migration ändert
Versionen, Abhängigkeiten und ein Migrationsfall: ethers wirft bei einer revertierten Transaktion einen Fehler, viem gibt den Receipt ohne Fehler zurück.

Wenn ein Nutzer in einer Anwendung auf Ethereum auf „Bestätigen“ klickt, durchläuft der Code mehrere Schritte, bevor er ein Ergebnis anzeigt: Er bereitet den Contract-Aufruf anhand der ABI vor, fordert die Signatur bei derWalletan, sendet die Transaktion an einenRPC-Node, wartet, bis sie in einen Block aufgenommen wird, und übersetzt den Receipt in eine Meldung.ethers.jsundviemsind die beiden TypeScript-Bibliotheken, mit denen dieser Ablauf geschrieben wird, und jede legt fest, wie die einzelnen Schritte abgebildet werden und was passiert, wenn einer davon fehlschlägt.
Für eine neue TypeScript-Anwendung ist viem heute die Wahl, die zum übrigen Ökosystem passt: wagmi 3 setzt viem als Abhängigkeit voraus, und Hardhat 3 bietet eine darauf basierende Toolbox. Bei einer Anwendung, die bereits mit ethers v6 läuft, liegt das Migrationsrisiko nicht im Umschreiben der Aufrufe, sondern darin, dass beide Bibliotheken auf dieselben Ereignisse unterschiedlich reagieren. Das Warten auf den Receipt löst in ethers eine Exception aus, wenn die Transaktion revertiert, während viem den Receipt mit dem Status reverted zurückgibt. Eine Migration, die Zeile für Zeile übersetzt, kann deshalb einen Vorgang als abgeschlossen anzeigen, der im Netzwerk fehlgeschlagen ist.
Welche Versionen aktuell sind und wer von welcher abhängt
ethers v6 wurde im Februar 2023 veröffentlicht, die neueste Version ist6.17.0 vom 18. Juni 2026; v5 ist auf npm weiterhin unter dem Tag legacy-v5 (5.8.0) verfügbar. viem hat Version 2.0 im Januar 2024 veröffentlicht, und die 2er-Linie erhält weiterhin neue Releases: Zwischen dem 26. Oktober und dem 8. November 2026 erschienen sechs Versionen, von 2.57.12 bis2.57.17. Version 3.0 befindet sich unter dem npm-Tag next in Vorbereitung (3.0.0-next.14 vom Oktober) und ist damit noch keine stabile Version für den Produktivbetrieb.
Bei neuen Projekten geben die Abhängigkeiten im Ökosystem den Ausschlag.wagmi3.7, die React-Hooks-Bibliothek zur Anbindung von Wallets, deklariertviem 2.x als zwingende Abhängigkeit, und derdie auf viem basierende Toolbox von Hardhat 3setzt viem 2.47.6 oder neuer voraus. Ein Frontend mit wagmi lädt viem ohnehin; ethers zusätzlich für die Contract-Aufrufe einzubinden bedeutet, zwei Datenmodelle und zwei Fehlerhierarchien im selben Bundle zu pflegen.
Provider und Signer versus Clients und Actions
ethers organisiert den Code um zustandsbehaftete Objekte: einen Provider, der mit dem Node kommuniziert, einen Signer, der signiert, und einen Contract, der ABI, Adresse und eines der beiden Objekte zusammenführt, sodass contract.withdraw(amount) in einem einzigen Aufruf vorbereitet, signiert und sendet. viem trennt einen Public Client, der liest, von einem Wallet Client, der signiert, und stellt jede Operation als Action mit expliziten Parametern bereit: readContract, simulateContract, writeContract oder waitForTransactionReceipt. Der resultierende Code ist bei einfachen Aufrufen länger, lässt sich aber leichter nachvollziehen, wenn eine Operation Simulation, Signatur und Warten kombiniert, weil jeder Schritt einen Wert zurückgibt, den der nächste übernimmt.
Der zweite Designunterschied ist die Typisierung. viem leitet Funktionsnamen, Argumente und Rückgabetypen über die Bibliothek ABIType aus der ABI ab, sofern diese mit as const oder inline deklariert ist, und dieTypeScript-Dokumentationsetzt TypeScript 5.0.4 oder neuer voraus. Ein falsch geschriebener Funktionsname oder ein Argument mit falschem Typ fällt bereits beim Kompilieren auf. Die Inferenz gleicht den Code mit der deklarierten ABI ab, nicht mit dem deployten Contract: Verweist die Adresse auf eine andere Version des Contracts, kann der Compiler das nicht erkennen. Diese Prüfung ist Aufgabe der Tests gegen das Netzwerk.
Wenn eine revertierte Transaktion als abgeschlossen erscheint
Nehmen wir als hypothetisches Beispiel eine Anwendung, mit der sich per Klick Mittel aus einem Einlagen-Contract abheben lassen. Die Version mit ethers v6 sendet die Transaktion mit contract.withdraw(amount), wartet mit await tx.wait() und zeigt „Auszahlung abgeschlossen“ an, wenn keine Exception auftritt; der catch-Block zeigt den Fehler. Dieser Code deckt den Fall ab, dass die Transaktion in einen Block aufgenommen wird, aber revertiert, weilwait() den Receipt prüftund bei Status 0 einen Fehler CALL_EXCEPTION mit der Meldung „transaction execution reverted“ auslöst.
Das Team migriert zu viem und übersetzt Zeile für Zeile: writeContract sendet die Transaktion und gibt deren Hash zurück, waitForTransactionReceipt wartet auf den Receipt. Die try/catch-Struktur bleibt erhalten, das Verhalten ändert sich jedoch. In viem 2.57.17 gibtwaitForTransactionReceiptden Receipt zurück, ohne dessen Status zu prüfen, und derReceipt-Formatterübersetzt den Wert 0x0 in status: 'reverted'; das Promise wird nur bei einem Timeout oder einem Fehler bei der Node-Abfrage abgelehnt. Hebt ein anderer Nutzer zwischen Versand und Aufnahme in den Block ab und reicht das Guthaben der Einlage nicht mehr aus, wird die Transaktion aufgenommen, revertiert und verbraucht Gas, während die migrierte Oberfläche „Auszahlung abgeschlossen“ anzeigt.
Ist das Problem erkannt, ist die Korrektur klein: prüfen, ob receipt.status den Wert 'reverted' hat, und diesen Fall als Fehler behandeln, oder das Warten in eine Funktion kapseln, die das bisherige Verhalten nachbildet. Schwierig ist, das Problem vor dem Produktivbetrieb zu finden. Eine Migration zwischen Bibliotheken braucht Tests für jedes mögliche Ergebnis des Ablaufs (abgelehnte Signatur, revertierte Transaktion, in der Wallet ersetzte Transaktion, nicht antwortender Node) und nicht nur für den Erfolgsfall. viem deckt zudem die Ersetzung ab: waitForTransactionReceipt erkennt, ob die Transaktion durch eine andere mit derselben Nonce ersetzt wurde, und klassifiziert den Grund als cancelled, replaced oder repriced. Auch für dieses Ergebnis braucht die Oberfläche eine eigene Meldung.
Eine Simulation vor dem Senden reserviert den State nicht
DieDie Dokumentation zu writeContractweist darauf hin, dass die Action nicht prüft, ob der Schreibvorgang gelingen wird, und empfiehlt, vorher simulateContract aufzurufen. Diese Action führt den Aufruf aus, ohne ihn zu verbreiten, und gibt das Ergebnis oder den Ablehnungsgrund zurück; ethers bietet dieselbe Prüfung mit staticCall auf der Contract-Methode. Die Simulation dient dazu, vor der Signaturanfrage einen verständlichen Fehler anzuzeigen, etwa ein unzureichendes Guthaben, statt eines generischen Fehlers bei der Gasschätzung in der Wallet.
Die Simulation bildet den State des abgefragten Blocks ab, nicht den des Blocks, in den die Transaktion aufgenommen wird. Im Beispiel der Auszahlung besteht die Transaktion die Simulation und revertiert anschließend, weil sich der State zwischen den beiden Abfragen geändert hat. Simulation und Prüfung des Receipts sind zwei verschiedene Kontrollen, die eine vor der Signatur, die andere nach der Aufnahme in den Block, und keine ersetzt die andere.
Bundle-Größe: Was vor der Angabe einer Zahl zu messen ist
Eine Kilobyte-Angabe ohne Version, Imports und Bundler erlaubt keinen Vergleich zwischen ethers und viem. viem ist in unabhängige Actions gegliedert, die Tree-Shaking entfernen kann, wenn sie nicht importiert werden, und das Endergebnis hängt auch von den Wallet-Connectoren und der Bundler-Konfiguration ab. Für ein Produkt zählt das JavaScript, das auf der Seite, auf der signiert wird, im Browser ankommt, gemessen mit demselben Bundler und denselben Operationen in beiden Varianten: Wallet verbinden, Guthaben lesen und eine Transaktion senden.
ethers.js vs. viem: Die Migrationskosten liegen in der Fehlerbehandlung
viem löst zwei reale Probleme gut: Es erkennt Aufruffehler gegenüber der deklarierten ABI bereits beim Kompilieren und macht jeden Schritt des Ablaufs explizit, sodass sich Simulation, Signatur, Aufnahme in den Block und Ersetzung getrennt behandeln lassen. Für ein neues Frontend mit React und wagmi bringt eine andere Bibliothek für die Contracts eine zusätzliche Abhängigkeit ohne erkennbaren Vorteil. ethers v6 wird weiterhin gepflegt, mit einer im Juni 2026 veröffentlichten Version, und eine damit laufende Anwendung wird durch eine Migration nicht sicherer: Sie gewinnt Typen und Konsistenz mit wagmi und muss dafür jede Stelle überprüfen, an der der Code davon abhängt, wie ethers seine Fehler auslöst.
Wenn migriert wird, kommt es auf die Reihenfolge an: zuerst eine Bestandsaufnahme der Fehler, die die Oberfläche verarbeitet, dann Tests, die jeden davon gegen ein lokales Netzwerk auslösen, und erst danach das Ersetzen der Aufrufe. Das Erscheinen von viem 3 ändert an diesem Vorgehen nichts; solange es unter dem Tag next steht, wird ein Projekt im Produktivbetrieb auf der 2er-Linie entwickelt.
Unser Team entwickelt das Frontend und dieSmart Contractsdezentraler Anwendungen, von einemMVPbis zum laufenden Betrieb, und der Leitfaden zuzur Entwicklung einer dAppbehandelt die übrigen Produktentscheidungen. Wenn Sie eine Migration erwägen,erzählen Sie uns davonwelche Abläufe die Anwendung hat und welche Fehler sie ihren Nutzern heute anzeigt.
- ethers.js v6.17.0 release (GitHub)
- ethers.js v6 source: TransactionResponse.wait (provider.ts)
- ethers.js v6 documentation
- viem 2.57.17 release (GitHub)
- viem source: waitForTransactionReceipt
- viem source: transaction receipt formatter
- viem: TypeScript
- viem: writeContract
- wagmi 3.7.11 on npm
- @nomicfoundation/hardhat-toolbox-viem 5.0.7 on npm
Häufige Fragen
Planen Sie ein Blockchain-Projekt?
Von der Idee bis zum Produkt müssen Strategie und Technologie Hand in Hand gehen.







