на чём работает этот сайт
Стек
Технологии, которые используются в проекте, и роль каждой из них.
браузер
- React 19
Одно дерево компонентов: сервер рендерит готовый HTML, а браузер подхватывает его через hydration.
- TypeScript
Типизировано всё, а типы API общие для клиента и сервера.
- React Router
Одна таблица маршрутов для сервера и браузера. Ленивые страницы загружаются ещё до рендера.
- TanStack Query
Данные запрашиваются на уровне маршрута заранее, а после hydration страница читает уже готовый кеш.
- Zustand
Только локальное состояние интерфейса: например, открыт ли модальный диалог. Серверные данные остаются в TanStack Query.
- i18next
Русский и английский с поддержкой SSR: язык определяется на сервере, а после hydration клиент продолжает работать с той же локализацией.
- Sass
SCSS и CSS Modules. Цвета вынесены в дизайн-токены, поэтому в стилях нет случайных значений и вся палитра управляется из одного места.
сервер
- Bun
Runtime и менеджер пакетов для монорепозитория. Запускает TypeScript напрямую и не требует отдельного шага сборки для серверного кода.
- Fastify
Веб-сервер для SSR, сессий и прокси на /api. На каждый запрос генерируется свой CSP nonce.
- Hono
API-слой. Для каждого маршрута схема и обработчик описаны вместе, поэтому валидация и OpenAPI генерируются из одного источника.
- Zod
Схемы для валидации запросов и данных. Из тех же схем генерируется OpenAPI, поэтому правила не приходится описывать дважды.
- Redis
Хранилище сессий в production. Сессии не зависят от памяти конкретного процесса и сохраняются между перезапусками приложения.
- PostgreSQL
База для заметок и остального содержимого сайта. Живёт в кластере под управлением оператора CloudNativePG.
- Drizzle
Схема и запросы к Postgres на TypeScript. Типы берутся из той же схемы, из которой собираются миграции.
- WebAuthn
Вход в админку по passkey: пароля нет нигде, подпись проверяется на сервере.
deploy
- Vite
Собирает клиент и сервер, а в development подключается к Fastify и отвечает за dev-сервер и HMR.
- PurgeCSS
Убирает неиспользуемые стили из production-сборки. Для классов в kebab-case используется свой extractor, чтобы нужный CSS не удалялся по ошибке.
- Vitest
Юнит-тесты лежат рядом с кодом и запускаются в CI. Для покрытия задан порог, ниже которого сборка не проходит.
- Biome
Линтер и форматтер для всего монорепозитория. Один конфиг в корне задаёт общие правила для всех приложений.
- Stylelint
Проверяет стили так же, как Biome проверяет код: порядок свойств, вложенность и запрет литеральных цветов вместо токенов.
- Knip
Находит мёртвый код: неиспользуемые файлы, экспорты и зависимости. Запускается в CI вместе с остальными проверками.
- Docker
Оба приложения собираются в отдельные образы прямо из монорепозитория. API-образ получается минимальным и не тащит за собой node_modules.
- k3s
Лёгкий Kubernetes для одной небольшой ARM-машины в Hetzner. Хватает для деплоя и управления сервисами без лишней инфраструктуры.
- GitLab
Здесь живёт репозиторий и CI/CD. Перед деплоем запускаются те же проверки, что и локально, поэтому поведение окружений не расходится.
- Cloudflare
DNS и туннель перед кластером. Входящий трафик идёт через Cloudflare, поэтому серверу не нужно открывать порты наружу.
- Sentry
Собирает ошибки из браузера и с сервера в одном месте, чтобы видеть всю картину по приложению.