Wnętrze ciemnego pokoju do czytania zbudowanego z Next.js 14 i Bun
Deweloperzy kochają przepisywać blogi. To już jest mem: zamiast pisać posty, burzymy stary stack i przebudowujemy interfejs od zera co sześć miesięcy. Proces prawie zawsze skutkuje szablonem z fabryki. Ale czasami trafiamy na kod źródłowy, gdzie autor poświęcił więcej uwagi szczegółom.
Pewnego dnia przeglądałem repozytorium woosal1337/blog — to osobista strona dewelopera Ege Celebi. Projekt zgromadził nieco ponad 300 gwiazdek na GitHubie. W środku kryją się interesujące rozwiązania do generowania grafik, typografii i pracy z MDX.
Pod maską
Nie ma tu ciężkiego CMS-a jak Ghost czy Strapi. Autor wybrał statyczne generowanie i wysoką szybkość ładowania.
Build opiera się na trzech rzeczach:
- Next.js 14 z App Router i React 18.
- Bun jako menedżer pakietów i runtime.
- Biome do lintowania i formatowania kodu.
Bun oszczędza czas na instalację zależności, a Biome zastępuje klasyczną kombinację ESLint i Prettier. Aby uruchomić linter z auto-naprawą, projekt używa polecenia bun run check.
Do stylowania używany jest Tailwind CSS. Ustawienia kolorów i tokenów są wyodrębnione do pliku app/globals.css. Geist Sans obsługuje czytanie artykułów, a Geist Mono jest używany do bloków kodu.
Okładki bez designerów i Midjourney
Głównym wyróżnikiem repozytorium jest generowanie banerów dla artykułów. Zwykle autorzy albo szukają odpowiedniego obrazka na Unsplash, generują obrazy sieciami neuronowymi, albo tworzą karty we Figma.
Ege rozwiązał problem inaczej. W pliku lib/contour.ts znajduje się algorytm, który pobiera tytuł posta i zamienia go w wzór konturowy. Otrzymujesz deterministyczny baner SVG. Każdy tytuł odpowiada własnemu unikalnemu rysunkowi i nie trzeba wywoływać zewnętrznych usług.
Ten sam znak konturowy jest używany jako logo i favicon, zachowując zjednoczoną tożsamość.
Płynne szkło i animacje ASCII
Wizualnie strona wygląda jak ciemna strona edytorska. Design używa ultra-cienkich obramowań (hairline borders) i ujednoliconej krzywej animacji dla przejść.
Interfejs zawiera kilka wizualnych odkryć:
- Okrągłe kontrolki z efektem płynnego szkła.
- Przyciemnione tagi dla kategorii i etykiet.
- Lewostronny spis treści artykułu z markerem nawigacji, który płynnie przewija się wzdłuż. Zachowanie markera jest wzorowane na komponencie LineNav.
- Żywe powierzchnie ASCII. W folderze
components/blocks/ascii/znajdziesz animowany torus (słynny ascii donut), cyfrowy deszcz, plasmę i efekty tunelu. Autor przeniósł je z biblioteki soft-club-ui i przemalował, aby pasowały do monochromatycznej palety strony.
Struktura projektu i MDX
Wszystkie artykuły są przechowywane bezpośrednio w drzewie stron App Router: app/(website)/blog/(post)/[slug]/page.mdx.
To podejście łączy logikę routingu i treść. Komponenty UI są wyraźnie rozdzielone:
- Folder
components/ds/zawiera wielokrotnego użytku podstawowe elementy systemu projektowego. - Folder
components/blocks/przechowuje złożoną logikę domenową i animacje.
Jak uruchomić lokalnie
Będziesz potrzebować Node.js w wersji 20 lub wyższej oraz zainstalowanego Bun. Nie trzeba konfigurować zmiennych środowiskowych.
Sklonuj repozytorium i uruchom lokalny serwer:
bun install
bun dev
Aby sprawdzić z lintem i sformatować kod:
bun run check
Dlaczego warto patrzeć w te źródła
Repozytorium warto otworzyć, jeśli planujesz zbudować własną stronę lub szukasz czystych przykładów architektury frontendu. W kodzie możesz podłapać:
- Konfigurację Biome w projekcie Next.js.
- Implementację generowania kart wektorowych na podstawie tekstu.
- Integrację Canvas i efektów ASCII w komponentach React.
- Organizację tokenów Tailwind w jednym pliku CSS.
Kod jest na licencji MIT, ale treść tekstowa i obrazy są chronione prawem autorskim. Kopiowanie artykułów nie jest dobrym pomysłem, ale studiowanie architektury i stosowanie pomysłów we własnym projekcie to świetny plan.
Powiązane projekty