go-react-saas is a reusable fullstack monorepo for building social networks, forums, SaaS products, marketplaces, and community apps with a shared Go API, PostgreSQL database, Docker-based infrastructure, and React / React Native clients.
This repository provides a production-minded starting point for fullstack products that need:
- a typed mobile frontend
- a modular Go API
- explicit PostgreSQL persistence
- session-based authentication with refresh-token rotation
- multi-tenant SaaS foundations with organizations and subscriptions
- containerized local development
- predictable smoke and QA scripts
The codebase is intentionally generic. Core modules can be composed and extended without assuming a single business vertical.
The default Docker Compose project name is go-react-saas, which keeps generated container, network, and volume names stable across environments.
- Go
- Gin
- PostgreSQL
pgxpool- JWT authentication with access tokens + refresh tokens
- explicit SQL queries without an ORM
- React Native with Expo
- React-compatible structure for additional clients
- TypeScript
- React Navigation
- React Query for auth/session orchestration
- Docker
- Docker Compose
- GitHub Actions for QA automation
.
├─ apps/
│ └─ mobile/
│ ├─ App.tsx
│ ├─ babel.config.js
│ ├─ e2e/
│ ├─ scripts/
│ └─ src/
│ ├─ api/
│ ├─ components/
│ ├─ screens/
│ ├─ store/
│ ├─ theme/
│ └─ utils/
├─ docs/
│ └─ ARCHITECTURE.md
├─ infra/
│ └─ docker-compose.yml
├─ scripts/
│ ├─ qa-lite.ps1
│ ├─ smoke-all.ps1
│ └─ smoke-api.ps1
├─ services/
│ └─ api/
│ ├─ cmd/api/
│ └─ internal/
│ ├─ features/
│ └─ platform/
├─ AGENTS.md
├─ CHANGELOG.md
├─ CODE_OF_CONDUCT.md
├─ CONTRIBUTING.md
└─ README.md
The API uses a feature-first structure with a small shared platform layer.
services/api/cmd/api/main.gois the composition rootservices/api/internal/platformcontains cross-cutting concerns such as config, database setup, middleware, logging, and shared errorsservices/api/internal/featurescontains domain modules such asauth,users,chat,posts,comments,notifications,files, andbilling
Each feature follows the same shape:
handler.goservice.gorepository.gomodel.goroutes.go
This keeps routing, business logic, and SQL separated while making new modules easy to add.
For a deeper breakdown, see docs/ARCHITECTURE.md.
The mobile app is organized around generic product surfaces:
- authentication
- home feed
- chat
- notifications
- profile
- session restoration and refresh-token aware auth state
Within apps/mobile/src:
apicontains REST clientshookscontains React Query-powered auth/session hooksscreenscontains route-level UIshared/uicontains reusable UI primitives and tokensshared/layoutcontains global layout and navigation shellsshared/feedbackcontains reusable loading, error, and empty statesstorecontains token/session persistencethemecontains shared design tokensutilscontains shared helpers
The current frontend shell is designed to be reused and extended rather than tied to a single product concept.
- Node.js 20+
- npm
- Go 1.23+ with toolchain support
- Docker Desktop or Docker Engine
Copy .env.example to .env and provide a strong JWT_SECRET before starting the stack.
PowerShell:
$env:JWT_SECRET='replace-with-a-random-secret-at-least-32-characters-long'
$env:APP_BASE_URL='http://localhost:18080'
docker compose up --build -dBash:
export JWT_SECRET='replace-with-a-random-secret-at-least-32-characters-long'
export APP_BASE_URL='http://localhost:18080'
docker compose up --build -dThe API is exposed on http://localhost:18080.
Optional Stripe billing variables:
$env:STRIPE_SECRET_KEY='sk_test_...'
$env:STRIPE_WEBHOOK_SECRET='whsec_...'
$env:STRIPE_PRICE_ID='price_...'Health check:
curl http://localhost:18080/healthPowerShell:
cd services/api
$env:DATABASE_URL='postgresql://app:app@localhost:5432/app?sslmode=disable'
$env:JWT_SECRET='replace-with-a-random-secret-at-least-32-characters-long'
go run ./cmd/apiBash:
cd services/api
export DATABASE_URL='postgresql://app:app@localhost:5432/app?sslmode=disable'
export JWT_SECRET='replace-with-a-random-secret-at-least-32-characters-long'
go run ./cmd/apicd apps/mobile
npm install
npm run startOther launch targets:
npm run android
npm run ios
npm run webFor physical devices, set:
EXPO_PUBLIC_API_URL=http://<LAN_IP>:18080Backend:
cd services/api
go test ./...
go build ./cmd/apiMobile:
cd apps/mobile
npx tsc --noEmit
npx expo export --platform android --output-dir .expo-auditRepository-wide QA:
powershell -ExecutionPolicy Bypass -File .\scripts\qa-lite.ps1 -ApiBaseUrl http://localhost:18080Backend billing is already wired for:
POST /billing/checkoutGET /billing/subscriptionPOST /billing/webhook
Required environment variables for a live Stripe flow:
STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETSTRIPE_PRICE_IDAPP_BASE_URL
APP_BASE_URL should be the public URL that Stripe redirects back to after checkout. In local Docker runs, http://localhost:18080 is fine for backend verification. For device testing or hosted environments, use a reachable public or LAN URL instead.
Codex MCP Stripe reference config is stored in config.toml. The shared Codex config on this machine now also includes:
[mcp_servers.stripe]
url = "https://mcp.stripe.com"Use the existing vertical-slice pattern and keep naming generic.
- Add or update a migration in
services/api/internal/platform/db/migrations. - Create a new feature folder under
services/api/internal/features/<feature>. - Implement
model.go,repository.go,service.go,handler.go, androutes.go. - Keep SQL in repositories and HTTP concerns in handlers.
- Register the feature in
services/api/cmd/api/main.go. - Add tests before expanding the public API surface.
Current SaaS-oriented backend foundations include:
- organizations for tenant identity
- sessions for refresh-token lifecycle
- subscriptions for billing state
- billing endpoints for Stripe checkout and webhook flows
- Add API client functions in
apps/mobile/src/api. - Add or extend screens in
apps/mobile/src/screens. - Extract reusable UI into
apps/mobile/src/shared/ui. - Keep layout concerns in
shared/layoutand stateful feedback inshared/feedback. - Keep tokens and storage concerns centralized in
themeandstore. - Re-run TypeScript and smoke checks after changes.