Zum Inhalt springen
  • Startseite
  • Über mich
  • Beiträge
  • Kontakt

Beiträge

Mein Portfolio auf die harte Tour bauen

Die vollständige Geschichte des Aufbaus einer Portfolio-Website von Anfang bis Ende - nicht nur der Code, sondern jede Entscheidung auf dem Weg. UX/UI-Design von Grund auf lernen, Infrastruktur auf einem selbstgehosteten NAS einrichten, bevor es auf einem VPS in Produktion geht, einen vollständigen SSR-Stack mit TanStack Start wählen, eigene ESLint-Regeln schreiben, Docker-Pipelines konfigurieren und jede Komponente zuerst in Figma entwerfen. Eine bewusste Übung eines Senior Frontend-Entwicklers, tiefer zu gehen als nötig - und mit einem deutlich breiteren Skillset auf der anderen Seite herauszukommen.

Der Ausgangspunkt: Warum überhaupt eine eigene Portfolio-Website bauen?

Ich hatte jahrelang als Frontend-Entwickler gearbeitet — Vue, React, in Branchen von Automobil über Logistik bis Versicherung. Meine tägliche Arbeit hat mir viel über den Bau von Produktionssoftware beigebracht, aber sie hielt mich auch in einem bestimmten Rahmen. Ich schrieb ausschließlich Frontend-Code, arbeitete mit Backend-Entwicklern und Designern zusammen und lieferte umfangreiche und gut durchdachte Features. Aber ich hatte selten die Gelegenheit, initiale Architekturentscheidungen zu treffen, Infrastruktur aufzusetzen oder über den gesamten Lebenszyklus einer Anwendung vom Design bis zum Betrieb nachzudenken.

Ich wusste auch, dass ich später in die Freiberuflichkeit wechseln wollte. Nicht sofort, aber ich wollte bereit sein, sobald der Zeitpunkt gekommen ist. Eine Portfolio-Website war der offensichtliche erste Schritt. Und wenn ich schon eine bauen würde, warum sollte ich die Chance nicht nutzen, um die Lücken in meinem Skillset zu füllen?

Also setzte ich mir zwei Ziele:

  • 1. Ein professionelles Portfolio erstellen, das repräsentiert, wer ich als Entwickler und Mensch bin.
  • 2. Den Entwicklungsprozess nutzen, um praktische Erfahrung in Bereichen zu sammeln, die ich üblicherweise bisher nicht direkt berührt habe — UX/UI-Design, DevOps, SSR-Architektur, Self-Hosting, CI/CD, Teststrategie, Barrierefreiheit und Sicherheit.

Das zweite Ziel ist der Grund, warum alles, was folgt, für ein Portfolio übertrieben klingen mag. Ist es auch. Das ist der Sinn dahinter.

Designen lernen: die UX/UI-Phase

Ich war Frontend-Entwickler, kein Designer. Ich konnte jedes Design umsetzen, das man mir gab, aber selbst eines von Grund auf erstellen? Das war Neuland. Also habe ich mich, bevor ich irgendeinen Code-Editor öffnete, in einem UX/UI-Kurs mit Fokus auf Figma eingeschrieben.

Der Kurs gab mir ein strukturiertes Fundament: Layout-Prinzipien, Typografie-Systeme, Abstands-Skalen, Farbtheorie, komponentenbasiertes Design-Denken. Er gab mir auch eine neue Wertschätzung für die Designarbeit, die ich jahrelang umgesetzt hatte, ohne die Begründung dahinter vollständig zu verstehen. Nach dem Kurs begann ich den eigentlichen Designprozess für mein Portfolio. Ich sammelte Screenshots von Entwickler-Portfolios, die ich bewunderte, legte sie in ein Figma-Inspirationsboard und annotierte, was mir an jedem gefiel — nicht die oberflächliche Ästhetik, sondern die strukturellen Entscheidungen. Wie sie Hero-Sections handhabten. Wie sie Erfahrungsbereiche organisierten, ohne vertrauliche Projektdetails preiszugeben. Wie viel Whitespace sie verwendeten. Dann baute ich mein eigenes Design-System: eine monochromatische Farbpalette, eine Typografie-Skala und ein 8pt-Abstands-Raster. Von dort arbeitete ich Wireframes für alle vier Seiten (Home, Über mich, Kontakt, Beiträge) in Graustufen durch, bevor ich visuelles Design anwendete. Alle Inhalte zu schreiben, bevor ich etwas designte, war die beste Entscheidung, die ich in dieser Phase getroffen habe. Es bedeutete, dass ich für echten Text designte, nicht für Platzhalterinhalte. Die Figma-Datei durchlief mehrere Runden: Grau-Wireframes, dann visuelles Design zuerst auf der Home-Seite, dann Erweiterung des Systems auf die restlichen Seiten, dann mobile Anpassung bei 375px, dann Interaktionszustände. Jede Runde war zeitlich begrenzt, um mich davon abzuhalten, endlos zu optimieren.

Ich werde noch einen eigenen Beitrag über den Designprozess an sich schreiben — was ich aus dem UX/UI-Kurs gelernt habe, wie ich das Design-System angegangen bin und welche spezifischen Entscheidungen ich für jede Seite getroffen habe.

Den Stack wählen: Warum TanStack Start?

Für eine Portfolio-Website hätte ein statischer Seitengenerator wie Astro oder sogar eine einfache Vite-React-App mehr als ausgereicht. Aber ich hatte eine spezifische Anforderung: serverseitiges Rendering. Ich wollte, dass mein Portfolio vollständig auf dem Server gerendert wird für SEO, und ich wollte SSR tiefgehend verstehen - nicht nur ein Framework nutzen, das es abstrahiert.

Ich evaluierte mehrere Optionen und entschied mich für TanStack Start. Es baut auf Vite auf, bietet dateibasiertes Routing, enthält Server-Funktionen out-of-the-box und - entscheidend - es gab mir SSR ohne die meinungsstarken Konventionen von etwas wie Next.js. Ich wollte die SSR-Primitive verstehen, nicht einfach einem Framework vertrauen, das sie handhabt.

Für das Styling wählte ich Panda CSS - eine Zero-Runtime CSS-in-JS-Lösung, die Styles zur Build-Zeit extrahiert. Das war wichtig für die SSR-Kompatibilität: Traditionelle Runtime-CSS-in-JS-Bibliotheken können Flash-of-Unstyled-Content-Probleme beim serverseitigen Rendering verursachen. Panda CSS eliminiert das vollständig. Ich kombinierte es mit Ariakit für barrierefreie, ungestylte Komponenten-Primitive.

Der Stack war am Ende:

  • TanStack Start - als Framework (SSR, Routing, Server-Funktionen)
  • React 19 - als UI-Bibliothek
  • Panda CSS - für Styling (Zero-Runtime, SSR-kompatibel)
  • Ariakit - für barrierefreie Komponenten-Primitive
  • TypeScript - im strikten Modus durchgehend

War dieser Stack für ein Portfolio übertrieben? Absolut. Aber SSR vom Framework-Level aufwärts zu lernen - Hydration, Server-Funktionen, Data Loader zu verstehen - war eines der Kernziele des Projekts.

Ich werde einen detaillierten Beitrag über meinen Stack-Vergleich und die spezifischen Trade-offs schreiben, die zu diesen Entscheidungen geführt haben.

Das Boilerplate: Von einem Fundament starten

Ich habe das Projekt nicht von Grund auf aufgesetzt. Im Laufe der Zeit hatte ich ein persönliches React-Boilerplate mit Konfigurationen und Patterns zusammengestellt, die ich in verschiedenen Projekten erprobt hatte. Das nutzte ich als Grundlage und generierte dann frische TanStack-Start- und Vite-Projekte, um neue Patterns oder Konfigurationsupdates auszuwählen.

Dieser hybride Ansatz gab mir das Beste aus beiden Welten: bewährte Konfigurationen, denen ich vertraute, plus die neuesten Scaffolding-Verbesserungen der Tool-Autoren. Ich integrierte TanStack-spezifisches Routing und SSR-Setup aus dem generierten Projekt, während ich meine bestehenden TypeScript-, ESLint- und Projektstruktur-Konfigurationen beibehielt.

Apropos ESLint - hier begann das Over-Engineering wirklich sichtbar zu werden. Am Ende schrieb ich 23 benutzerdefinierte ESLint-Regeln über mehr als 2.000 Zeilen Konfiguration. Regeln für Namenskonventionen, Projektstruktur-Durchsetzung, Panda-CSS-Style-Formatierung, i18n-Konformität und Typsicherheit. War das für ein Portfolio notwendig? Nein. Habe ich enorm viel über AST-basiertes Linting und Code-Qualitätsdurchsetzung gelernt? Ja.

Ein Beitrag über mein ESLint-Setup und benutzerdefinierte Regeln kommt definitiv - es war einer der unerwartet lehrreichsten Teile des Projekts.

Infrastruktur zuerst: GitLab, Docker und CI/CD

Die meisten Entwickler würden ein Portfolio auf Vercel oder Netlify deployen und weitermachen. Ich wollte die gesamte Deployment-Pipeline verstehen, also habe ich meine eigene aufgesetzt. Ich betreibe ein NAS zu Hause und habe eine selbstgehostete GitLab-Instanz darauf konfiguriert. Das wurde mein Git-Remote, mein CI/CD-Runner und mein erstes Deployment-Ziel. Der Plan war, das NAS während der Entwicklung als Staging-Umgebung zu nutzen und dann die Produktion auf einen VPS zu verlagern, sobald die Seite bereit für den Launch war.

Die CI/CD-Pipeline läuft durch fünf Stufen: Vorbereitung, Abhängigkeiten, Test, Build und Deploy. Ich verwende einen Docker-out-of-Docker-Ansatz, bei dem der GitLab-Runner den Docker-Socket des Hosts nutzt, was performanter als Docker-in-Docker ist und den Layer-Cache des Hosts teilt. Das Docker-Setup selbst ist ein Multi-Stage-Build: eine Builder-Stufe mit allen Abhängigkeiten, eine Deps-Stufe mit nur Produktionsabhängigkeiten und eine finale Runtime-Stufe mit Nginx und Node.js.

Ich habe auch Renovate für automatisiertes Dependency-Management konfiguriert. Es läuft nach Zeitplan, erstellt Merge Requests für Updates und hält alles aktuell ohne manuelle Arbeit. Das alles einzurichten hat deutlich länger gedauert als einfach auf Vercel zu pushen. Aber ich verstehe jetzt Containerisierung, CI/CD-Pipelines, Reverse Proxies und Deployment-Strategien auf einem Niveau, das ich nie erreicht hätte, wenn ich eine verwaltete Plattform genutzt hätte.

Ich werde einen Beitrag über das vollständige DevOps-Setup schreiben - die NAS-zu-VPS-Migrationsstrategie, Docker-Optimierung und die CI/CD-Pipeline-Konfiguration.

Backend-Abstecher: Node.js, Express und MongoDB

Auch wenn ich Frontend-Entwickler bin und nicht vorhabe, Backend-Entwickler zu werden, wollte ich genug Backend-Wissen, um das Gesamtbild zu verstehen. Durch private Projekte außerhalb dieses Portfolios lernte ich Node.js mit Express und MongoDB.

Dieses Hintergrundwissen beeinflusste mehrere Entscheidungen im Portfolio-Projekt: wie ich über API-Design nachdenke, wie ich Server-Funktionen in TanStack Start strukturiert habe und wie ich die Grenze zwischen Client und Server angehe. Zu verstehen, was auf der anderen Seite des API-Aufrufs passiert, macht mich zu einem besseren Frontend-Entwickler - ich kann informiertere Gespräche mit Backend-Kollegen führen und bessere Architekturentscheidungen treffen. Ich beanspruche aber keine Backend-Expertise. Aber genug zu wissen, um einen Server aufzusetzen, eine API zu designen und eine Datenbank zu verwalten, gibt mir eine breitere Perspektive, die ich in jedes Frontend-Projekt einbringe.

Produktions-Deployment: Vom NAS zum VPS

Die Deployment-Strategie war bewusst zweiphasig. Während der Entwicklung lief alles auf meinem NAS: GitLab, die Docker-Registry und die deployete Anwendung. Das gab mir eine eigenständige Umgebung, in der ich Dinge kaputt machen konnte, ohne Konsequenzen.

Für die Produktion war der Plan immer, auf einen VPS umzuziehen. Das umfasste die Bereitstellung eines Servers mit Ubuntu LTS, die Härtung mit SSH-Key-Authentifizierung, Firewall-Regeln und Fail2ban, dann die Einrichtung von Nginx als Reverse Proxy mit Let's-Encrypt-SSL-Zertifikaten. Die Anwendung läuft hinter Nginx über PM2, das Prozessmanagement, Clustering und automatische Neustarts übernimmt. Der Übergang vom NAS zum VPS bedeutete auch, die GitLab-CI/CD-Pipeline zu aktualisieren, um in eine andere Registry zu pushen und auf ein anderes Ziel zu deployen. Da die Pipeline durch Umgebungsvariablen abstrahiert war, war dieser Wechsel unkompliziert.

Ein eigener Beitrag über VPS-Bereitstellung, Sicherheitshärtung und die NAS-zu-VPS-Migration ist geplant.

Barrierefreiheit und Sicherheit: keine Nebensache

Zwei Bereiche, denen ich bewusst volle Aufmerksamkeit gewidmet habe, waren Barrierefreiheit und Sicherheit. Nicht weil eine Portfolio-Website ein Hochrisikoziel ist, sondern weil ich die Gewohnheiten und das Wissen für Projekte aufbauen wollte, in denen sie wirklich wichtig sind.

Für Barrierefreiheit habe ich WCAG 2.2 AA-Konformität zusammen mit BITV 2.0 angestrebt - dem deutschen Barrierefreiheitsstandard, der mit der EU-Webzugänglichkeitsrichtlinie übereinstimmt. Das bedeutete semantisches HTML durchgehend, korrekte Überschriftenhierarchie, vollständige Tastaturnavigation, ausreichender Farbkontrast, ARIA-Labels wo native Semantik nicht ausreichte, und Tests mit Screenreadern. Ich habe auch die neueren Anforderungen von WCAG 2.2 wie Mindest-Zielgrößen und Fokussichtbarkeit berücksichtigt.

Für Sicherheit implementierte ich serverseitige Eingabevalidierung, Inhaltsbereinigung, Content-Security-Policy-Header und Dependency-Auditing. Ich plante Rate-Limiting für Formularübermittlungen und konfigurierte Sicherheitsheader in Nginx.

Beide Bereiche haben mir beigebracht, dass Barrierefreiheit und Sicherheit keine Features sind, die man am Ende hinzufügt - es sind Ansätze, mit denen man von Anfang an baut. Beides nachträglich einzubauen ist deutlich schwieriger, als es von Beginn an richtig zu machen.

Ich werde separate Beiträge über meine Barrierefreiheits-Implementierung (einschließlich BITV-2.0-Besonderheiten) und meinen Sicherheitshärtungs-Ansatz schreiben.

Testing: den Kreis schließen

Testing war ein weiterer Bereich, in dem ich tiefer ging, als ein Portfolio es streng genommen erfordert. Ich habe drei Ebenen eingerichtet: Unit-Tests mit Vitest für Hilfsfunktionen und Custom Hooks, Komponententests mit React Testing Library für UI-Verhalten und End-to-End-Tests mit Playwright für kritische Benutzerabläufe über mehrere Browser hinweg.

Ich habe auch axe-core für automatisierte Barrierefreiheitstests in der Pipeline integriert und Coverage-Reporting konfiguriert. Das Ziel war nicht 100% Coverage - es war der Aufbau einer Teststrategie, die ich mit Zuversicht in zukünftige Projekte mitnehmen kann.

Ein Beitrag über meine Teststrategie und die praktischen Trade-offs zwischen den Testebenen ist geplant.

Was ich wirklich gelernt habe

Rückblickend sind die technischen Fähigkeiten, die ich erworben habe, offensichtlich: Figma, SSR, Docker, CI/CD, Self-Hosting, Barrierefreiheitsstandards, Sicherheitshärtung. Aber die weniger offensichtlichen Lektionen waren wertvoller. Der Designprozess hat verändert, wie ich über Frontend-Arbeit denke. Nachdem ich den UX/UI-Kurs durchlaufen und meine eigene Seite designt habe, verstehe ich Designentscheidungen auf einem Niveau, das ich vorher nicht hatte. Ich bin jetzt ein besserer Mitarbeiter für Designer, weil ich mehr von ihrer Sprache spreche.

Over-Engineering ist eine valide Lernstrategie - solange man weiß, dass man genau das tut. Ich würde ein Kundenprojekt niemals so bauen. Aber für ein persönliches Projekt mit dem expliziten Ziel zu lernen, hat sich die zusätzliche Komplexität in Wissen ausgezahlt. Der Schlüssel ist, ehrlich über den Trade-off zu sein: Das hat Monate gedauert, nicht Wochen.

Den gesamten Stack zu verstehen macht dich besser in deinem Verantwortungsbereich. Ich bin kein Backend-Entwickler, und ich bin kein DevOps-Ingenieur. Aber zu wissen, wie Deployment funktioniert, wie Server konfiguriert werden und wie APIs designt werden, macht mich zu einem effektiveren Frontend-Entwickler. Ich stelle bessere Fragen, mache weniger Annahmen und kann produktivere Gespräche mit dem Rest des Teams führen.

Etwas von Anfang bis Ende zu bauen ist der beste Lehrer. Kein Kurs, Tutorial oder Dokumentation kommt annähernd daran heran, tatsächlich selbst etwas auszuliefern, mit all den unordentlichen Entscheidungen und unerwarteten Problemen, die damit einhergehen.

Was kommt als Nächstes

Dieses Portfolio ist live, aber es ist nicht fertig - und wird es wahrscheinlich nie sein. Ich plane, weiter am Design zu iterieren, Beiträge hinzuzufügen und es als Spielwiese für neue Techniken zu nutzen. Die Infrastruktur ist bewusst darauf ausgelegt, das zu unterstützen: Die CI/CD-Pipeline, die Teststrategie und die Komponentenarchitektur machen es einfach, Dinge zu ändern, ohne sie kaputt zu machen.

Wenn du ein Entwickler bist und überlegst, dein eigenes Portfolio zu bauen, ist mein Rat einfach: Bau nicht nur eine Website. Bau etwas, das dir beibringt, was du wirklich lernen möchtest. Wenn das bedeutet, es zu over-engineeren, ist das in Ordnung. Sei einfach bewusst dabei.

Ich werde detailliertere Beiträge über bestimmte Phasen dieser Reise schreiben. Wenn eines der Themen, die ich erwähnt habe, interessant klingt, schau wieder vorbei - oder melde dich. Ich würde gerne hören, wie andere Entwickler ihre eigenen Portfolios angehen.

Dieser Beitrag ist Teil einer Serie. Detaillierte Beiträge zu einzelnen Themen - Designprozess, Stack-Entscheidungen, ESLint-Anpassung, DevOps-Setup, Barrierefreiheit, Sicherheit und Testing - kommen bald.

  • Startseite
  • Über mich
  • Beiträge
  • Kontakt