A full-stack app for invite-only circles: share posts and photos with people you trust. React + Express API, PostgreSQL via Prisma, JWT and Google sign-in.
- Groups with invite tokens: create a circle, share a join link, scoped group walls for posts
- Landing + Circles UX: marketing
Landingsection components; authenticated Circles list, Group wall, and Join flow
- Dual profanity filtering:
bad-wordsandmint-filteron titles, messages, and comments - Rate limiting: Express rate limit with optional Redis store for shared limits across instances
- Large uploads: JSON/body limit 30MB for rich image payloads
- JWT sessions plus Google OAuth (ID token verification on the server)
- bcryptjs for password hashing
- Helmet and structured error handling on the API; Sentry and Prometheus-style /metrics in production-oriented setups
- Posts: CRUD, likes, comments, tags, search, pagination, creator profiles
- Gravatar avatars from email
- Redux + Redux Thunk on the client; Material-UI v4 and mixed JS/TS components
- Prisma ORM with PostgreSQL (schema + migrations in
server/prisma) - TypeScript server (
tsxin dev,tscbuild); REST JSON API - Modular React UI (including
Landing/*,Circles/*,Form,Posts, etc.)
| Technology | Version | Purpose |
|---|---|---|
| React | 17.0.x | UI |
| Redux / Redux Thunk | 4.x / 2.x | State & async actions |
| Material-UI | 4.12.x | Components |
| React Router | 5.3.x | Routing (Switch / Route) |
| Axios | 1.6.x | HTTP client |
| TypeScript | 5.x | Partial typing (.tsx / .ts components) |
| Technology | Purpose |
|---|---|
| Node.js 18+ | Runtime |
| Express 4.x | HTTP API |
| Prisma | ORM & migrations (PostgreSQL) |
| PostgreSQL | Primary database |
| JWT / google-auth-library | Auth |
| bcryptjs | Password hashing |
| express-rate-limit + rate-limit-redis + ioredis | Rate limiting (Redis optional) |
| bad-words / mint-filter | Text filtering |
| helmet | Security headers |
| @sentry/node | Error reporting (when configured) |
| prom-client | GET /metrics |
- concurrently β client + server in
npm run dev - tsx β TypeScript server in development
- Jest β server tests
- ESLint β client lint (CRA)
- Email/password signup and sign-in (JWT)
- Google sign-in
- Protected API routes and client flows
- Create groups, list my circles, fetch a group by id
- Join via invite token (
/join/:inviteToken) - Posts can be scoped to a group (
groupId)
- CRUD posts, image field (base64), tags
- Like / unlike
- Comments (add, edit, delete) with ownership checks
- Search, creator filter, pagination
- User profiles
- Landing page at
/(composed fromclient/src/components/Landing/*) - Main app routes under
/posts,/circles,/auth, etc.
- GET /health β health check
- GET /metrics β Prometheus metrics (when enabled)
- Node.js 18+ recommended
- npm
- PostgreSQL (local or hosted, e.g. Supabase, Railway, Neon)
- Redis (optional; recommended in production for shared rate limits)
git clone <repository-url>
cd mern-memoriesnpm run install-allThis installs root, server, and client (client uses --legacy-peer-deps for peer compatibility).
Manual alternative:
npm install
cd server && npm install
cd ../client && npm install --legacy-peer-deps- Create a PostgreSQL database.
- Copy
server/env.exampletoserver/.envand setDATABASE_URL(seeenv.examplefor formats). - From
server/:
npx prisma migrate dev # apply migrations
# optional:
npm run prisma:seedKey variables (see server/env.example for full list):
| Variable | Purpose |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
JWT_SECRET |
Strong secret for signing JWTs |
GOOGLE_CLIENT_ID |
Google OAuth client ID (same idea as client if using Google login) |
PORT |
API port (server defaults to 5001 if unset) |
REDIS_URL |
Optional; enables Redis-backed rate limiting |
The CRA proxy in client/package.json points at http://localhost:5001. Change it if your API runs on another port.
From the repo root:
npm run dev- API:
http://localhost:5001(or yourPORT) - React:
http://localhost:3000
Separate terminals:
npm run server
npm run clientnpm run buildOutput: client/build. Serve statically and point the client at your deployed API base URL.
| Command | Description |
|---|---|
npm run dev |
API + React dev servers |
npm run server |
API only |
npm run client |
React only |
npm run build |
Production build of the client |
npm run test |
Server Jest tests |
npm run install-all |
Install all workspaces |
| Command | Description |
|---|---|
npm run dev |
tsx watch index.ts |
npm run build |
tsc β dist/ |
npm start |
Run compiled dist/index.js |
npm run prisma:migrate |
Prisma migrate dev |
npm run prisma:studio |
Prisma Studio |
npm run prisma:seed |
Seed script |
| Command | Description |
|---|---|
npm start |
CRA dev server |
npm run build |
Production bundle |
npm test |
CRA tests |
Unless noted, routes expect Authorization: Bearer <jwt> for protected handlers.
| Method | Path | Description |
|---|---|---|
POST |
/user/signup |
Register |
POST |
/user/signin |
Login |
POST |
/user/google |
Google token login |
| Method | Path | Description |
|---|---|---|
POST |
/groups |
Create group |
GET |
/groups/mine |
List my groups |
GET |
/groups/:id |
Get group |
POST |
/groups/join |
Join with invite token |
| Method | Path | Description |
|---|---|---|
GET |
/posts |
Paginated posts (auth) |
GET |
/posts/search |
Search (auth) |
GET |
/posts/creator |
By creator (auth) |
GET |
/posts/:id |
Single post (auth) |
POST |
/posts |
Create |
PATCH |
/posts/:id |
Update |
DELETE |
/posts/:id |
Delete |
PATCH |
/posts/:id/likePost |
Like / unlike |
POST |
/posts/:id/commentPost |
Add comment |
PATCH |
/posts/:id/comment/:commentId |
Edit comment |
DELETE |
/posts/:id/comment/:commentId |
Delete comment |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/metrics |
Metrics |
mern-memories/
βββ client/ # React app (CRA)
β βββ src/
β βββ actions/ # Redux actions
β βββ api/ # Axios instance
β βββ components/ # UI (Landing/, Circles/, Auth/, β¦)
β βββ reducers/
β βββ App.js
βββ server/ # Express API (TypeScript)
β βββ prisma/
β β βββ schema.prisma
β β βββ migrations/
β βββ controllers/
β βββ routes/
β βββ middleware/
β βββ config/ # e.g. Redis
β βββ utils/
β βββ index.ts
β βββ env.example
βββ package.json # Root scripts
βββ README.md
- Run
npm run buildinserver/and start withnpm start, or runtsx/node with migrations applied (prisma migrate deployin production). - Set
DATABASE_URL,JWT_SECRET, andREDIS_URL(production) on the host. - Deploy the
client/buildfolder to static hosting; configure the client to call your public API URL (proxy only applies in dev).
npm run testRuns server Jest tests from server/.
- Fork the repository
- Create a branch:
git checkout -b feature/your-feature - Commit and push
- Open a pull request
Please keep changes focused, match existing patterns, and run tests / client build where relevant.
ISC β see repository metadata.
Material-UI, Prisma, PostgreSQL, React, and the open-source packages this project depends on.
Built with the MERN spirit β today backed by PostgreSQL, Prisma, and TypeScript on the API.