Sie haben eine tolle Idee für eine neue App und Fragen sich jetzt, welcher Tech-Stack am besten für den MVP geeignet ist? Dann haben Sie den richten Artikel gefunden, denn genau diese Frage werden wir uns hier ausführlich widmen.
Achtung: Dieser Blogartikel ist „opinionated“. Ich gebe hier meine Meinungen und Erfahrungswerte aus zwei selbst gegründeten Startups und der Involvierung in weiteren Startup-Projekten weiter. Bei vielen meiner Meinungen ist die genaue Antwort „es kommt drauf an“. Aus Gründen des Pragmatismus, werde ich in diesen Artikel jedoch Farbe bekennen.
Was ist ein MVP?
Der Begriff wurde im Zuge der Lean-Startup-Methode geprägt. Eric Ries, der als Begründer dieser Methode gilt, hat den MVP-Begriffs in einem seiner Blogbeiträge wie folgt definiert:
First, a definition: the minimum viable product is that version of a new product which allows a team to collect the maximum amount of validated learning about customers with the least effort.
Lessons Learned: Minimum Viable Product: a guide (startuplessonslearned.com)
Es geht bei einem MVP also darum mit minimalen Aufwand das Maximum an Kundenvalidierung zu erhalten. Die meisten MVPs scheiten und das ist auch gut so. Deshalb müssen wir uns aber immer bewusst sein, dass ein MVP zur Validierung der Idee dient. Hier ist also Wartbarkeit und der perfekte Tech-Stack fehl am Platz. Es zählt Pragmatismus und Geschwindigkeit. Wenn sich unsere Idee als gut herausstellt, können wir immer noch die perfekte Architektur machen. 😉
Begriffsabgrenzung
Ich höre den Begriff MVP in einem anderen Kontext verwendet. Beispielsweise als Bezeichnung für einen Prototypen, einen Proof-of-Konzept oder für die ersten Versionen eines Produkts, das nach Prinzipien der agilen Softwareentwicklung erstellt wird. Dies sind also meistens Validierungsphasen in einem längeren Projekt. Man kann hier gerne den Begriff „MVP“ verwenden, jedoch sollte man sich bewusst sein, dass dieser Begriff nichts mit der Definition laut Lean-Startup zu tun hat und die Gedanken in diesen Artikel nur bedingt anwendbar sind.
Typische MVP-Organisation
Typischerweise wird ein MVP in einem sehr kleinen Team entwickelt. Denken Sie an einen Solopreneur, ein Startup-Team, dass aus 2 bis 4 Gründern besteht oder ein kleines Projektteam innerhalb einer etablierten Organisation, die für das MVP-Projekt freigestellt werden. In allen Szenarien gibt es jedoch meistens nur wenige Personen, die tatsächlich in das Programmieren der App involviert sind.
Apropos Minimal Viable: Im Startup-Umfeld gibt es den Begriff Minimal Viable Teams, auch bekannt als Startup Dream Team oder 3H Theory. Dieses Team besteht aus drei Personen(typen), die sich Kompetenzen teilen, auf ein bestimmtes Wissen spezialisiert sind und so in Summe alle relevanten Aktivitäten in einer Startup-Frühphase abdecken:
- Hacker: Zuständig für Entwicklung und Design.
- Hustler: Verantwortet Business-Themen wie Business Development, Vertrieb oder HR.
- Hipster: Kümmert sich um Produktmanagement und Marketing.
Auch im Dreamteam gibt es nur einen Steretyp, nämlich den Hacker, der Code schreibt.
Die Architektur deines MVPs
Bevor wir uns um einzelne Technologien Gedanken machen, möchte ich über die Architektur des MVPs sprechen. In den meisten Fällen wollen wir möglichst viele Benutzer erreichen und die Einstiegshürde für den Benutzer gering halten. Dabei eignen sich Web Apps recht gut. Diese können auf Desktops genauso wie am Tablet oder am Smartphone geöffnet werden. Anpassungen an spezielle Plattformen (wie bei Mobile Apps) sind nicht notwendig und das zusätzliche Testing für verschiedene Browser hält sich in Grenzen. Mehr dazu weiter unten.
In der Regel werdet ihr zentrale Daten austauschen wollen oder einen zentrale Geschäftslogik verwenden wollen. Deshalb wird eine Client/Server-Architektur in den allermeisten Fällen ebenso eine gute Wahl sein. Wenn ihr euch ganz sicher seit, dass ihr mit einem Monolithen (Client-only) ausreichen habt, dann könnt ihr auf den Server natürlich verzichten. Eventuell würde ich am Server eine Unterteilung zwischen Domänen- und Infrastrukturschicht einführen. Falls dieser Satz beim lesen kein „ja, macht Sinn“ hervorgebracht, würde ich es lassen. 😉
Die Kommunikation zwischen Client und Server würde ich über REST ausführen, da es weit verbreitet und gut unterstützt wird. Sollten Sie mit gRPC oder SOAP mehr Erfahrung haben, ist aber auch dies eine gute Alternative.
Für spezielle Szenarien kann auch eine Mobile App statt einer Web App geeignet sein. Hier gibt es aber zwei große Herausforderungen zu betrachten. Die erste, ist die Betriebssystemunterstützung. Typischerweise müssen wir Android und iOS unterstützen. Das bedeutet zusätzlichen Aufwand im vergleich zur Web App. Zumindest muss auf zwei Plattformen getestet werden, meistens ist auch ein zusätzlicher Programmieraufwand notwendig. Auch wenn eine Cross-Platform-Lösung verwendet wird, sind oft Anpassungen für das jeweilige Zielbetriebssystem notwendig.
Die zweite Herausforderung ist der App Store, über den die App verteilt wird. Apps können nicht einfach so in den App Store hochgeladen werden, sondern müssen gewisse Kriterien erfüllen und werden geprüft. Dies bedeutet oft Verzögerungen und zusätzliche Aufwände beim Deployment. Gerade beim MVP wollt ihr aber so rasch wie möglich deployen können, um beispielsweise Fehler auszubessern.
Wenn ihr einen guten Grund habt, eine Mobile App zu entwickeln, dann macht das. In den meisten Fällen ist die Web App aber die sichere Variante.
Nehmt Abstand von Architekturen wie Microservices, Self-Contained-Systems, Service-oriented Architecture oder Command Query Responsibility Segregation! Für einen MVP ist das Overkill. Auch wenn ihr die jeweiligen Architekturmuster gut beherrscht, so bringen sie doch Komplexität ins System, die ihr nicht haben wollt. Ihr müsst in dieser Phase in der Lage sein euch schnell zu bewegen und auf Änderungen zu reagieren.
Auch brauchen wir im MVP keinen API Gateway oder einen Distributed Cache. Messaging Systeme sind in der Regel ebenfalls überflüssig (und das sage ich, obwohl ich ein Freund von ereignisgetriebenen Architekturen bin).
Die richtigen Technologien
Hier ist der perfekte Tech-Stack für dein MVP:
- Frontend: Verwende die Technologien, du du kennst und gut beherrscht.
- Backend: Verwende die Technologien, du du kennst und gut beherrscht.
- Datenbank: Verwende die Technologien, du du kennst und gut beherrscht.
😯
Das ist jetzt vielleicht antiklimaktisch, aber ihr seit am besten mit Technologien beraten, die ihr schon gut kennt. Es ist jetzt nicht die Zeit ein neues Framework oder eine neue Programmiersprache zu lernen.
Wenn ihr euch in Angular wohl fühlt, verwendet Angular als Frontend. Ihr habt schon ein paar mal MariaDB verwendet? Super, das wird euer DBMS. Ihr schämt euch, weil ihr immer nur PHP und jQuery verwendet? Dann zeigt der Welt, dass man damit auch super MVPs machen kann! Du bist Flash-Profi? Okay… Irgendwo gibt es dann auch Grenzen. Wir leben nicht mehr in den 90ern und Flash ist seit 2020 offiziell Tod.
Durch die Verwendung von bekannten Technologien, können wir das MVP mit minimalen Aufwand und schnell erstellen. Wir wollen nicht zuerst eine neue Sprache lernen müssen, das wäre viel zu aufwendig. Außerdem wird auch die Fehlersuche mit uns neuen Technologien länger dauern als wie mit bekannten. Unsere ersten Kunden geben uns wertvolles Feedback und dieses wollen wir möglichst rasch umsetzen können.
Neue Problemstellungen
Manchmal kommen wir mit unseren vorhandene Wissen nicht weiter. Nehmen wir an, wir kennen uns gut mit PHP und Vanilla JS aus. Für unsere neue App wissen wir aber, dass Echtzeitkommunikation zwischen den Clients notwendig ist. Wie finden wir die beste Technologie dafür? Fragen wir doch einfach ChatGPT (oder ein anders LLM):
I'm developing a Minimal Viable Product (MVP) for my app idea. I have great knowledge with PHP and vanilla JavaScript, but for the MVP I'm going to need real-time communication between clients. It's important for me to develop the MVP fast, with minimal effort in learning new technologies. The technology should be widely adopted, so that I can quickly find help online.
Please suggest a tool, framework, library, etc that I can use for real-time communication between clients, with the given information.
ChatGPT schlägt uns Socket.IO vor und gibt uns auch eine Anleitung mit Code Beispielen, die wir zum Einstieg in Socket.IO verwenden können.
Falls uns der Vorschlag aus einem bestimmten Grund nicht gefällt, können wir natürlich auch um Alternativen fragen:
Can you please give me an alternative suggestion?
In meinem Versuch, hat ChatGPT Pusher als Alternative vorgeschlagen.
Ich verwende übrigens absichtlich Englisch als Anfragesprache, da ich erfahrungsgemäß hier bessere Antworten erhalte. „Your milage may vary“ bzw. „Dein Kilometerstand mag abweichen“. 🤷♂️
Tipp: Dein MVP beinhaltet einen AI-Algorithmus, aber du willst nicht die Zeit und die Kosten dafür aufbringen, eine eigen AI zu entwickeln um den Markt zu validieren? Oft kann in der MVP-Phase ein Wrapper zu ChatGPT eine gute Alternative sein. Das gilt natürlich nur, wenn dein USP nicht genau die AI-Funktion ist, sondern AI nur einen Teil deiner Kernfunktionalität abbildet.
Throw one away
Ein MVP priorisiert Time-to-Market über alles andere. Deshalb wird man gezwungenermaßen technische Schuld, insbesondere bei der Wartbsrkeit, Lesbarkeit des Codes, Performanz und der Testüberdeckung anhäufen. Wir gehen also bewusst das Risiko von hoher technischer Schuld ein.
Aus dem Standardwerk „The Mythical Man-Month“ gibt es die Idee von „Throw one away“:
In most projects, the first system built is barely usable….Hence plan to throw one away; you will, anyhow.
Fred Brooks, The Mythical Man-Month
Diese Aussage begründet sich auf den Umständen, dass die erste Version ein Software oft Fehler beinhaltet, wichtige Funktionen fehlen, eine schlechte Benutzeroberfläche haben und mehr. Die Gründe dafür sind zum einen, dass in der ersten Version noch zu wenige Feedback von echten Benutzern steckt (das ist ja auch die Motivation ein MVP zu machen). Zum anderen verstehen wir als Entwickler aber oft einfach die Problemstellung und die Lösungsansätze zu wenig, um machen deshalb suboptimale Implementierungen.
Halten wir also die letzten drei Gedanken fest:
- Wir verwenden einen Tech-Stack denn wir gut können, der aber nicht ideal für unsere App ist.
- Wir nehmen bewusst technische Schuld in Kauf.
- Wir planen damit, die erste Version unserer App sowieso wegwerfen zu müssen.
Diese drei Gedanken sollten uns darin bestärken, das MVP als Lern- und Wegwerf-Objekt zu betrachten. Wenn unsere Idee am Markt erfolgreich validiert, können wir unsere Erkenntnisse in das „richtige“ Produkt einfließen lassen und haben somit einen Starkvorteil.
Gedanken zur Teststrategie
Zur Teststrategie bei der MVP-Entwicklung könnte ich einen eigenen Artikel schreiben. Hier möchte ich aber zumindest die wichtigsten Gedanken zu diesen Thema angeführt werden.
Teststufen
In klassischen Testkonzepten wird ein Fokus auf viele automatisierte Komponententests (Unit Tests), etwas weniger Komponentenintegrationstests (Integration Tests) und noch weniger Systemtests gelegt. Dieser Zusammenhang wird gerne mittels einer Testpyramide visualisiert. Je niedriger in der Pyramide, desto schneller sind diese Tests, aber sie decken jeweils nur einen kleineren Teil des Systems pro Testfall ab. Deshalb benötigen wir in den unteren Ebenen auch eine höhere Zahl an Testfällen. Die Testabdeckung und die Laufzeit nimmt mit höhe der Stufe ab. Ebenso auch die Automatisierbarkeit.
Beim MVP würde ich jedoch versuchen, möglichst wenig Unit Tests einzusetzen und eher auf System- und Systemintegrationstests zu bauen. Unit Tests neigen zur Wartungsanfälligkeit und verlangsamen durch den Wartungsaufwand das Vorankommen in der MVP-Phase. Ihre Vorteile wie Unterstützung beim Design, Testen ohne Abhängigkeit von anderen Modulen und Teams oder der Beitrag zur Softwaredokumentation können sie in diesem Szenario nur schwer ausspielen.
Sollen wir ganz auf Unit Tests verzichten? Nein, definitiv nicht! Wenn Unit Tests hilfreich sind um beispielsweise Randfälle und verschiedene Zustände eines Algorithmus zu testen, dann kann und soll man natürlich Unit Tests verwenden. Ich würde beim MVP jedoch keinen Wert auf rigoros getestete Klassen legen.
Integrations- und Systemtests sind hier häufig effektiver. Das System hat typischerweise noch eine überschaubare Komplexität und die man kann mit relativ wenigen, relativ simplen Tests eine große Testabdeckung erzielen. Jedenfalls sollte eine Testsuite zusammengestellt werden, die vor jeden neuem Deployment ausgeführt werden soll.
Testarten
Der Fokus bei Testarten sollte eindeutig bei den funktionalen Tests liegen. Nicht-funktionale Tests können ergänzend ausgeführt werden, jedoch sollten diese auf die wirklich wichtigen Qualitätsanforderungen des MVPs beschränkt sein und pragmatisch durchgeführt werden.
Das bedeutet z. B. auch, dass wir Tests zur Browserkompatibilität auf das Minimum reduzieren. Wenn wir uns Statistiken zur Browsernutzung ansehen, können wir mit Chrome bereits > 60% der Benutzer abdecken. Mit Safari sind es in Summe über 80%. Unsere Teststrategie könnte also lauten: Alle Systemtests werden mir Chrome ausgeführt, zusätzlich führen wir einige Smoketests mit Safari aus.
Testing in Production
Unser MVP hat ja den Zweck Marktfeedback zu erhalten. Deswegen ist Testing in Production ein idealer Ansatz für uns. Testing in Production bedeutet nicht, dass man blind ungetesteten Code auf Main committed oder den Kunden das testen überlässt. Es geht viel mehr darum Testen bis in den Produktivbetrieb zu denken.
Die Produktivumgebung ist die ultimative Referenz für unsere App. Es kommt häufig vor, dass uns bestimmte Produktivdaten oder das Zeitverhalten der Produktivumgebung überraschen. Man könnte versuchen, entsprechende Staging Environments und synthetische Testdaten zu erstellen, aber das bedeutet wieder viel Aufwand.
Stattdessen empfehle ich Maßnahmen umzusetzen, die uns rasch Feedback von der Produktionsumgebung liefern. Dies beinhaltet z.B.: Tracking der App Usage, Aufzeichnung von Queries, ein gutes Logging und das Erstellen von Alarmieringen.
Softwareverteilung
Unsere App muss ultimativ auch zum Kunden gelangen. Hier lautet meine eindeutige Empfehlung Cloud Computing einzusetzen. Cloud Computing hilft uns zu skalieren, schnell auf neue Anforderungen einzugehen und wir müssen uns nicht mit Infrastrukturthemen herumschlagen. Die Argumente im Detail:
- Skalierbarkeit: Zu Beginn kennen wir das Lastverhalten unseres Systems sehr schlecht. Wir wollen weder die Hardware unterdimensionieren und Performanceprobleme habe, noch überdimensionieren und zu viel zahlen. Cloud Computing hilft uns mit wenig Ressourcen anzufangen und sukzessive zu skalieren, sofern notwendig.
- Kosten: Cloud-Dienste sind für heterogene Workloads relativ günstig. Vor allem, wenn man neben den reinen Mietkosten auch noch die Arbeitszeit hinzurechnet. Viele Cloud-Anbieter bieten kostenlose Stufen ihrer Dienste an. Für den Anfang können diese Stufen oftmals ausreichend sein.
- Administration: Wir müssen uns keine Gedanken über Sicherheits-Patches, Best Practices oder Konfiguration von Services machen. In der MVP-Phase möchte man lieber Funktionen entwickeln als Updates zu installieren. Und Zeit für Troubleshooting der Infrastruktur hat auch niemand.
- Verfügbarkeit von Diensten: Wenn wir doch einmal einen zusätzlichen Dienst neben unserem Server und unserer Datenbank benötigen, kann man den in der Cloud schnell bereitstellen.
Falls bereits ausreichende Kenntnisse in der Serveradministration vorhanden sind, kann ein kleiner Linux-VPS eine Alternative sein. Hier sollte man aber die Grundinstallation von Webserver und Datenbank aus dem Effeff beherrschen. Man sollte sich auch darüber bewusst sein, dass die regelmäßige Wartung, wie das Einspielen von Updates, Zeit in Anspruch nimmt.
Vom MVP zum wartbaren Produkt
Um vom Minimal Viable Produkt zu einem wartbaren Produkt zu kommen, gibt es einige generelle Strategien. In der Praxis hängt der konkrete Weg von vielen Rahmenbedingungen ab, die ich im Zuge eines Blogartikels nicht alle ausführen kann. Eine der Herausforderungen, auf die ich hier nicht eingehen kann, ist der Parallelbetrieb von Alt- und Neu-Software.
Wenn wir das neue Produkt entwerfen, können wir alle gesammelten Informationen und Daten des MVPs in den Entwurf einfließen lassen. Es ist nun möglich eine Architektur zu erstellen, die besser auf die Qualitätsanforderungen eingeht und besser passende Technologien zu wählen. In dieser Phase geht es nun zu einem langfristig wartbaren Produkt, wo Time-to-Market nicht mehr über allem anderen priorisiert wird.
Rewrite
Beim Rewrite werfen wir den MVP komplett weg und schreiben das Produkt von neuen. Typischerweise möchte man die Daten der MVP-Benutzer auf das stabile Produkt migrieren oder zumindest die Datenbank wiederverwenden.
Refactor
Bei dieser Strategie wird eine Beibehaltung der Code Base angestrebt. Alle Unzulänglichkeiten des MVPs werden durch Refactorings ausgebessert und die technische Schuld abgearbeitet.
Diese Strategie ist eine gute Wahl, wenn der Tech-Stack des MVPs bereits geeignet für den langfristigen Betrieb scheint und noch nicht zuviel technische Schuld angesammelt wird.
Strangler Fig
Strangler Fig ist ein Architekturmuster, bei dem ein Altsystem sukzessive in ein neues System migriert wird. Dabei werden nach und nach Funktionen der alten Anwendung durch neue Komponenten ersetzt. Typischerweise wird Strangler Fig im Zusammenhang mit Microservices und verteilten System eingesetzt. Jede neue Komponente stellt dabei beispielsweise einen eigenständigen Service dar.
Setzte dein MVP um!
Mit dieser Anleitung steht dem ersten Schritt zum MVP nichts mehr im Wege! Auch wenn ich keine Liste von konkreten Technologien geliefert habe, sollte es nun klar sein, mit welchen Tech-Stack man beginnt.
Wenn es dann um die Migration des MVPs in ein wartbares Produkt geht, gibt es noch einige Herausforderungen zu meistern. Ich stehe gerne mit Rat und Tat zur Seite, um die technologische Seite deines Startups in den Griff zu bekommen!