This repository is a working demo of a full-stack application:
- Tanstack Start + React Query + React Hook Form
- Orval (OpenAPI code generator for TypeScript)
- Spring Boot + OpenAPI + Session-based auth
- ElectricSQL (Real-time support for PostgreSQL)
- Complex translation system
- Liquibase + PostgreSQL
- Memory optimization and profiling for Spring Boot application
- Cookie authentication: Either same-site or cross-site cookies (with proxy server on client)
- Server APIs
- Client sign-in + sign-up pages (React Hook Form)
- Integrate forms with APIs
- Handle accessibility (Check Lighthouse in Chrome Devtools for suggestions)
- Real-time support: Setup ElectricSQL for this project template
- Way 1: Pure Socket + STOMP support
- Way 2: ElectricSQL sync engine or other similar open-source
- Way 3: Convex
- ElectricSQL authentication
- Deployment
- Render
- electric-server
- admin-monitor
- openapi-server
- tanstack-start-client-app: https://tanstack-start-client-app.onrender.com
- Neon (PostgreSQL with easy logical replication support, but need to be careful with scale down to zero)
- Need to set ELECTRIC_REPLICATION_IDLE_TIMEOUT, so Electric can scale down
- To prevent storage bloat, Neon automatically removes inactive replication slots after approximately 40 hours
- Github Actions: For running free more complex cron jobs
- Wake up ElectricSQL server for example (if you set ELECTRIC_REPLICATION_IDLE_TIMEOUT to scale down after certain idle time)
- cron-job.org: For simple pinging servers every 15 mins so they don't go to sleep
- Render
- Email sending support
- Dev env: Use Mailtrap
- Prod env: You can setup Mailtrap, Resend, Mailgun, ...
- Password reset
- Remember me token for longer session duration
Client (Tanstack Start):
cd tanstack-start-client-app
pnpm install
pnpm copy-env
pnpm devServer (Spring Boot):
- I prefer using IntelliJ to run the server
- But you can also use VSCode to run
- But before running the server, make sure to run docker compose properly and copy environment variables
cd openapi-server
pnpm install
pnpm copy-env
docker compose up -dTanstack Start:
-
React Query: Data fetching and caching
-
Orval: Type-safe API client generation from OpenAPI spec
-
ElectricSQL client: Real-time read path with PostgreSQL
- NOTE: I haven't implemented true local-first approach to support real-time write path yet
-
MobX: State management for UI state
-
React Hook Form: My own convention of composing nested independent forms + monitoring form states
-
CSS modules + Tailwind
-
Theme provider with system theme support and FOUC prevention
-
Translation support with react-i18next
-
Test ID naming (See doc)
Spring Boot:
-
OpenAPI: API documentation and contract
-
Security: Basic auth, CSRF protection for SPA, and CORS configuration
-
ElectricSQL proxy server: A proxy layer between client and ElectricSQL server to handle authentication and filtering
-
Spring Audit: Auditing entity with @CreatedBy createdAt, @LastModifiedBy updatedAt, etc. (See doc)
-
Liquibase: Database migrations (See doc)
-
Testing: Unit tests with Surefire and integration tests with Failsafe (Bonus: Testcontainers for running PostgreSQL Docker containers during tests) (See doc)
-
Memory optimization + Profiling: (See doc)
openapi-server: Spring Boot application
src/main/java/com/tudope/openapi_server: Java source codesrc/main/resources/db/changelog: Liquibase changelog filessrc/main/resources/application.yaml: Application configuration (with multiple profile variants)src/test/java/com/tudope/openapi_server: Java test codedocker-compose.yaml: Docker compose config for PostgreSQL and ElectricSQL serverpom.xml: Maven build file + dependencies
tanstack-start-client-app: Tanstack Start application
-
public: Static assets -
src/api/axios.ts: Override Axios instance -
src/api/fetch.ts: Override Fetch instance -
src/components: Pure React components without any data -
src/electric-shapes: ElectricSQL shape definitions -
src/features: Feature-specific components and logic -
src/orval: Generated API client code thanks to Orval -
src/providers/csrf-provider.tsx: CSRF token provider making sure the app has initialized CSRF token -
src/providers/store-provider.tsx: MobX store provider -
src/providers/theme-provider.tsx: Theme provider to manage light/dark/system theme and prevent FOUC -
src/routes/__root.tsx: Root route of the app -
src/routes/index.tsx: Home route -
src/routes/_authenticated/app.tsx: App route after user has signed in -
src/routes/_unauthenticated/signin.tsx: Sign-in route -
src/routes/_unauthenticated/signup.tsx: Sign-up route -
src/server-actions: Global server actions -
src/stores: MobX stores for UI state management -
src/styles: Global style + route-level styles -
src/utils: Utility functions for class names, tailwind, etc. -
src/router.tsx: Application router configuration -
orval.config.ts: Orval configuration file to generate API client from OpenAPI spec
-
pnpm outdated: Check for outdated dependencies for clientpnpm up --latest: Update dependencies to latest versions for client- Or choose certain dependencies to update by specifying package names
-
pnpm install --resolution-only: Check for outdated dependencies or potential version conflicts -
pnpm why <package-name>: Check why a certain package is installed and which other packages depend on it -
mvn versions:display-dependency-updates: Check for outdated dependencies for server -
mvn versions:display-plugin-updates: Check for outdated plugins for server- Update
pom.xmlwith latest versions for dependencies
- Update
-
mvn wrapper:wrapper -Dmaven=3.9.14: Update Maven wrapper to a certain version -
/usr/libexec/java_home -V: Check installed Java versions in macOS -
ls /opt/homebrew/opt/ | grep jdk: Check installed Java versions in Homebrew -
Use Github Dependabot to automate dependency updates (recommended) and security patches (optional)
- For CSS file to not complain about "Unknown at rule" when using Tailwind directives in VSCode:
- Install
Tailwind CSS IntelliSenseextension in VSCode - Add file association in VSCode settings ->
"css": "tailwindcss"
- Install
-
For IntelliJ TypeScript support to function properly, make sure you are not marking
node_modulesas "Excluded"node_modulesneeds to be automatically marked by IntelliJ as "library root"
-
For IntelliJ Spring Boot in Windows WSL2 to show Beans, Health, Mappings, and Environment properly
- Make sure you change the run configuration to include
-Djava.rmi.server.hostname=localhost
- Make sure you change the run configuration to include
- To test CORS + cookie issues, use Ngrok to create HTTPS public URLs for both backend and frontend
- Then, adjust CORS allowed origins and server url properly
- Now, you can simulate how it works in production with HTTPS and cross-site cookies
- But after playing around, I recommend using same-site cookies for fewer headaches
- Use either actual same domain or reverse proxy
- In this template, we use reverse proxy thanks to Nitro
