A modern template for exploring React Server Components (RSC) with React Router, powered by Vite.
- 🧪 Experimental React Server Components
- 🚀 Server-side rendering with RSC
- ⚡️ Hot Module Replacement (HMR)
- 📦 Asset bundling and optimization with Vite
- 🔄 Data loading and mutations
- 🔒 TypeScript by default
- 🎉 TailwindCSS for styling
- 📖 React Router docs
- 📚 React Server Components guide
Install the dependencies:
npm installStart the development server with HMR:
npm run devYour application will be available at http://localhost:12968.
Create a production build:
npm run buildRun the production server:
npm startSessions are stored in PostgreSQL. A session with a non-null expires value is
removed automatically when that value is in the past. The cleanup job runs
once per hour through PostgreSQL pg_cron; sessions with expires IS NULL are
treated as non-expiring.
The development container builds .devcontainer/postgres.Dockerfile, which
installs pg_cron and loads it with shared_preload_libraries. Applying the
Prisma migrations creates both the extension and the
cleanup-expired-sessions job. The job runs at the start of every hour in UTC.
After pulling this configuration into an existing development environment, rebuild and recreate only the database container so the new image is used, then apply the pending migration:
docker compose -f .devcontainer/docker-compose.yml build db
docker compose -f .devcontainer/docker-compose.yml up -d db
pnpm exec prisma migrate deployThe existing db_data volume can be kept. Delete it only when resetting local
database data is acceptable:
docker compose -f .devcontainer/docker-compose.yml down -vThe production database administrator must install and enable the pg_cron
extension. The exact package name depends on the PostgreSQL distribution; for
PostgreSQL 18 on Debian/Ubuntu it is commonly postgresql-18-cron.
- Add
pg_crontoshared_preload_librariesinpostgresql.confand setcron.database_nameto the application database. - Restart PostgreSQL.
- Apply the Prisma migrations as a user allowed to create extensions and
schedule cron jobs. The migration creates
pg_cron, theSession.expiresindex, and the cleanup job:
pnpm exec prisma migrate deployUse SELECT * FROM cron.job; to verify the schedule and
SELECT * FROM cron.job_run_details ORDER BY start_time DESC LIMIT 20; to
inspect recent runs. Ensure the role used by pg_cron can connect to the
application database and delete rows from "Session".
If enabling extensions is not possible, configure the host's system cron or
the hosting provider's scheduled job to execute the same DELETE statement
with psql once per hour. Do not use an in-process Node.js timer as the only
production scheduler, because it is not reliable across restarts and multiple
application instances.
Learn more about React Server Components with React Router in our comprehensive guide.
This template comes with Tailwind CSS already configured for a simple default starting experience. You can use whatever CSS framework you prefer.
Built with ❤️ using React Router.