Перейти к содержимому
Supastack
RU
Тема
ВойтиПолучить Supastack
Все статьи

Как создать Web и Mobile SaaS на Next.js и Expo (Руководство по монорепозиторию)

Практическое руководство по кроссплатформенной архитектуре: объединение Next.js 16 и React Native Expo в монорепозитории pnpm с общими Better Auth и Drizzle ORM.

Noah Zixin Zhang2 мин чтения

Как организовать совместное использование кода между Next.js и Expo?

Это зависит от границ модулей и настройки сборщиков. Наиболее надежный подход — использование pnpm и Turborepo для изоляции моделей баз данных, схем валидации и контрактов API в независимые внутренние пакеты. Сервер Next.js 16 выполняет Drizzle ORM напрямую к PostgreSQL, тогда как приложение Expo взаимодействует через типизированные HTTP-эндпоинты и надежно хранит токены сессий в expo-secure-store. supastack поставляется с готовой конфигурацией без конфликтов между Metro и Turbopack.

Главная трудность кроссплатформенного SaaS: Конфликт сборщиков

Каждый основатель понимает, что мобильное приложение многократно повышает удержание пользователей благодаря пуш-уведомлениям и присутствию на экране смартфона. Однако объединение Next.js и React Native Expo в одном репозитории сопряжено со сложностями.

Next.js опирается на Turbopack или Webpack для сред Node и Edge, тогда как Expo использует сборщик Metro для среды выполнения React Native. Непродуманный обмен кодом приводит к сбоям: Metro пытается загрузить модули Node вроде crypto, а Turbopack спотыкается о мобильный синтаксис JSX. Решение кроется в строгой инкапсуляции пакетов.

Проектирование общих пакетов: Аутентификация, схемы и контракты

В надежном монорепозитории клиентские приложения (apps/web и apps/mobile) должны быть лишь тонкими слоями интерфейса. Бизнес-логика и модели данных размещаются во внутренних пакетах в каталоге packages/:

@supastack/db: Содержит таблицы Drizzle ORM, связи и файлы миграций. Только серверные процессы подключаются к базе данных; клиенты импортируют исключительно выведенные типы TypeScript.

@supastack/auth: Настраивает Better Auth с двумя точками входа: серверные обработчики роутов и клиентский SDK, используемый веб- и мобильным приложением.

@supastack/config: Проверяет переменные окружения на этапе сборки с помощью Zod, исключая падения в продакшене из-за пропущенных настроек.

// packages/auth/src/client.ts
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";

export function createCrossPlatformAuthClient(baseURL: string, storage?: any) {
  return createAuthClient({
    baseURL,
    plugins: storage ? [expoClient({ scheme: "myapp", storage })] : [],
  });
}

Единая авторизация: Cookies в Вебе, SecureStore на Мобильных

Веб и мобильные платформы требуют разных механизмов сохранения сессий. В браузере Next.js устанавливает куки HTTP-only с параметром SameSite=Lax, обеспечивая защиту от CSRF и корректную гидратацию серверных компонентов.

На мобильных устройствах куки в WebViews ненадежны. Приложение Expo получает токен Bearer после завершения входа через OAuth или magic link и сохраняет его в Keychain iOS или Keystore Android с помощью expo-secure-store. Мобильные запросы содержат заголовок Authorization: Bearer <token>, валидируемый общим middleware Better Auth.

Пайплайн CI/CD и релизы: Vercel, EAS Build и синхронизация версий

Ведение Веба и Мобильного приложения в едином репозитории обеспечивает синхронный выпуск обновлений. При слиянии миграции в @supastack/db бэкенд Next.js за считанные секунды развертывается на Vercel или Cloud Run.

Одновременно с этим сервис Expo Application Services (EAS Build) компилирует нативные сборки для Apple TestFlight и Google Play. Фиксация версий общих пакетов в монорепозитории полностью исключает баги несовместимости, характерные для раздельных проектов.

Ваш следующий продукт начинается здесь.

Один платёж. Создавайте прибыльные продукты.