veröffentlicht am:
Lesedauer:
Lesedauer: 6 min

Next.js oder Remix.run?

Autoren
  • avatar
    Thomas Schefter

Bei der Suche nach einem Full-Stack JavaScript Framework gibt es heutzutage viele Lösungen. So viele, dass man von „Javascript Fatigue“ spricht. Also eine Übersättigung und Ermüdung des Marktes. Was heute noch als Hype und State of the Art gilt, kann in 6 Monaten bereits veraltet sein. Das macht es schwierig, die richtige Wahl zu treffen.

Als ich 2018 den Weg von Angular.js und Create React App (CRA) zu einem JS Framework suchte, welches Server-Side Rendering (SSR) beherrscht, kam eigentlich nur Next.js in Frage. Svelte, Remix, Astro oder Qwik gab es damals noch nicht.

Bei SSR (Server-Side Rendering) wird die Webseite am Server gerendert (ähnlich wie PHP) und an den Browser übermittelt. Im Browser wird diese statische Seite per JavaScript in eine dynamische WebApp „hydriert“. Im Gegensatz zu einer reinen PHP-Webseite kann sie nun wie eine Single Page Application (SPA) funktionieren. Die Vorteile von SSR gegenüber einer reinen SPA sind eine bessere Performance, der Verbleib sensibler Daten auf dem Server und vor allem die Möglichkeit für Suchmaschinen, den Inhalt zu lesen. Wenn man auf Suchmaschinen angewiesen ist, führt derzeit kein Weg an Server-Side Rendering vorbei.

Ein Vorteil eines Full-Stack-Frameworks besteht darin, dass Frontend und Backend nicht mehr getrennt sind. Dadurch entfällt die Notwendigkeit eines Frontend-Teams und separater Backend-Entwickler, die unterschiedliche Tools und Programmiersprachen verwenden.

Um solche Frameworks zu hosten, benötigt man oft einen Node.js-Server oder eine ähnliche Umgebung. Die üblichen Massenhoster bieten dies meist nicht an. Das Einrichten und Betreiben eines solchen Servers ist auch nicht jedermanns Sache.

Die Firma Vercel, die hinter Next.js steht und früher "Zeit" genannt wurde, erkannte frühzeitig, dass die Developer Experience (DX) ein wichtiger Faktor für den Erfolg eines Frameworks ist. Wenn es Entwicklern Spaß macht, mit dem Framework zu arbeiten, werden sie es immer wieder einsetzen. Vercel hat ein kleines Universum für automatisches Deploy, Hosting und viele Annehmlichkeiten rund um Next.js aufgebaut. Mit wenigen Klicks kann man, ohne besondere Backend-Kenntnisse, seine Webseite bei Vercel deployen. Im Laufe der letzten Jahre hat Vercel das immer weiter ausgebaut und sogar ehemalige Mitglieder des React Teams von Facebook eingestellt.

Ich hatte mich schon etliche Monate mit Next.js (https://nextjs.org) beschäftigt und kleinere Projekte, wie diese Webseite hier, umgesetzt, als ich auf Remix.run (https://remix.run) aufmerksam wurde. Ich hatte mit Next einige Probleme in einem Projekt, die Remix besser zu lösen schien. Remix wurde ab 2020 von den Machern des React Routers entwickelt und 2022 von Shopify übernommen. Mit der Version 13 hat Next.js einige Ideen von Remix (nested routes) übernommen und nutzt dafür als erstes Framework React Server Components (RSC).

Da ich mir nicht sicher war, welches der beiden Frameworks für mein aktuelles Projekt besser geeignet ist, habe ich einige Monate parallel mit Next.js und Remix entwickelt. Letztendlich habe ich mich für Remix entschieden, weil:

  • Remix nutzt an vielen Stellen wieder Webstandards, die in der Vergangenheit bei JS Frameworks etwas in Vergessenheit geraten sind. Den größten Aha-Effekt gibt es sicherlich bei der Übermittlung von Formularen. Das funktioniert in Remix sogar, wenn man JavaScript deaktiviert hat, da das HTML Form Element genutzt wird. Das erinnert einen ein wenig an PHP. Die Browser-eigenen APIs brechen den Request auch korrekt ab, wenn man währenddessen die Route wechselt. Bei Next.js ist Data Mutation Sache des Entwicklers. Man muss sich selbst um die Übermittlung, Status und Fehlerbehandlung kümmern.

  • in Next.js passieren mehr Dinge „magisch“ als in Remix. Sie funktionieren einfach, ohne dass man die Hintergründe genau verstehen muss. z.B. das Caching. Schwierig wird es dann, wenn man diesen „Next Way“ gerade nicht nutzen und diese eingebaute Funktion verändern möchte.

  • Next.js hatte eine extrem hohe Änderungsrate, die mich fast zur Verzweiflung trieb. Von 2020 bis 2022 gab es 5 große Versionssprünge (Version 9 bis 13). Bei kleineren Updates, wie der Link-Komponente, musste man „nur“ sämtliche Links im Projekt ändern. Ein Projekt vom Pages Router der Version 12 ins App Routing der Version 13 zu ändern, kommt praktisch einer Neuprogrammierung gleich. Man verbringt viel Zeit damit, mit der Entwicklung des Frameworks Schritt zu halten, anstatt sich um das eigentliche Projekt zu kümmern. Remix entwickelt sich ebenfalls schnell, verfolgt jedoch die Philosophie der Feature Flags. Dadurch kann man in Version 1 schrittweise die neuen Features der Version 2 über die remix.conf aktivieren und das Projekt schonend zur Version 2 migrieren.

  • Die Next.js-Macher beteuern zwar, dass ihr Framework plattformunabhängig ist, die volle Funktionalität (z.B. Image Optimization oder Middleware) gibt es nur, wenn man zu Vercel deployt. Bei kleineren Projekten kann man damit gut leben. Es ist sogar kostenlos. Sobald eine Webseite jedoch viel Traffic hat, kann das Hosting bei Vercel deutlich teurer sein als anderswo.

  • Remix kann relativ einfach auf verschiedenen Plattformen genutzt werden. Es gibt fertige Templates für Node.js, Express, AWS Lambda, Vercel, Cloudflare, Fly.io oder Netlify. Dass Remix früher und stabiler auf Cloudflare Workers lief, war für mich ein wichtiger Grund. Beim Deploy zu Cloudflare läuft die gesamte Webseite in der Edge in der Nähe der Benutzer auf weltweit über 200 Rechenzentren von Cloudflare. Zusätzlich kann man in Remix weitere Cloudflare-Produkte wie KV (Key Value Store), D1 (SQLite in der Cloud), WAF (Firewall), Worker Analytics, Queues usw. nutzen. Vercel hat inzwischen erkannt, dass es sinnvoll ist, neben dem Next.js-Projekt auch die Datenbanken und KV-Stores zu hosten, und bietet erste Produkte über Partnerschaften (mit Cloudflare, Upstash usw.) an.

Ich behaupte nicht, dass Remix besser ist als Next. Ich fand es für derzeit meine aktuellen Projekte besser geeignet. Vielleicht ändert sich das sogar noch, wenn der App Router von Next.js vollständig ausgereift ist. Beide Frameworks sind ähnlich und haben gute Ideen voneinander übernommen. Nachdem in der JavaScript Welt zuerst alles auf dem Client lief, fokussieren die Frameworks nun auf den Server. Fast wie zu guten alten PHP Zeiten ;-)

Folgende Probleme hatte ich bisher während meiner Arbeit mit Remix:

  • Remix läuft nicht auf Browsern, die nicht ES-2020 kompatibel sind. z.B. iOS 12 oder älter (natürlich auch nicht IE 11 und älter). Eventuell bekommen spätere Remix Versionen die Möglichkeit, Zielbrowser über browserlistrc einzustellen.
  • Netzwerk Fehler, die nicht vom Remix Server kommen (Proxy oder Firewall Fehler und Captchas) sind am Client schwer zu handeln, da der Client so etwas in den _data Responses nicht erwartet. Dieses Problem dürften andere Frameworks auch haben. Es bedarf einiger Einstellungen in CDN und Firewall. Seit Version 1.19. enthält Remix einen speziellen Header Eintrag um nicht-Remix Antworten erkennen zu können.
  • Hydration Errors sind ein gefürchtetes Problem aller React SSR Frameworks. Besonders seit React Version 18. Hydration Errors passieren, wenn der HTML DOM (durch Browser Plugins oder Scripte wie Adsense) während des Hydrierens geändert wird.
  • Race Conditions beim setzen von Cookies. Jeder Loader bzw. Action kann Cookies schreiben, was beim nested Routing schnell zu Problemen durch gegenseitiges überschreiben führen kann. Hier sollte man aufpassen, besonders bei der Flash Message Funktion von Remix.
  • Kein Remix Problem, sondern eine Cloudflare Funktion, aber trotzdem gut zu wissen: Web Streaming im Loader mittels Remix defer funktioniert in Cloudflare Pages nur, wenn kein allgemeines Caching per Page Rule für die Domain eingestellt ist. Cloudflare kann keine Daten aus dem Cache streamen.

Als Entwickler sollte man basierend auf den Projektanforderungen und Kenntnissen selbst entscheiden.