Overview
RUSH sells men’s streetwear: gym fits, everyday essentials and accessories. I built the store as a monorepo, with a Next.js 15 storefront, an Express REST API on MongoDB and a shared package of types and constants. It covers the whole shopping loop, from browsing and variants to checkout, order tracking and the admin behind it.
Problem
A fashion brand lives on drops. The store had to feel premium on a phone, find a product quickly in a growing catalogue, take an order from cart to confirmation, and give the team one place to run products, orders and customers.
My role
- Built the storefront, the API and the shared package, all in one npm-workspaces monorepo.
- Implemented auth with JWTs, refresh tokens and HttpOnly cookies, plus password reset and user and admin roles.
- Built the catalogue with debounced search, filters, sort and pagination, and product pages with size and colour variants.
- Built cart, wishlist and checkout with tax, shipping and coupons, then order tracking on a timeline.
- Built the admin dashboard for stats, products, orders and users.
Architecture
- FrontendNext.js 15 App Router and TypeScript, with Tailwind CSS, shadcn-style components and Framer Motion. Client state lives in Zustand.
- APINode.js and Express REST API with role-based access for users and admins.
- DatabaseMongoDB with Mongoose models, hosted on MongoDB Atlas.
- SharedA shared TypeScript package of types and constants used by both web and API.
- IntegrationsPayments (Stripe and Razorpay) and uploads (Cloudinary) are structured in, ready to be switched on.
- HostingStorefront on Vercel, API on Render.
Technology
Interface
- Next.js
- TypeScript
- Tailwind CSS
- Framer Motion
- Zustand
- React Hook Form
- Zod
API & data
- Node.js
- Express
- MongoDB
- Mongoose
- JWT
Delivery
- Vercel
- Render
- MongoDB Atlas
- npm workspaces
Engineering challenges
Sessions that stay out of JavaScript
A store holds addresses and order history, and tokens kept in browser storage are one XSS bug away from being stolen.
Finding the right fit fast
As the catalogue grows, a search request on every keystroke makes listings jumpy and loads the API.
A storefront that never shows blank
The API runs on a host that can be slow to wake or briefly unavailable, and an empty shop window loses the sale.
One contract across web and API
Two apps describing the same products and orders drift apart one field at a time.
Solution
- S1
Sessions that stay out of JavaScript
Short-lived JWTs with refresh tokens, both in HttpOnly cookies, and role checks on the API so admin routes are closed to everyone else.
- S2
Finding the right fit fast
Debounced search combined with filters, sort and pagination on the API, and size and colour handled as variants of one product rather than separate listings.
- S3
A storefront that never shows blank
The storefront falls back to mock data when the API is offline, so the catalogue still renders.
- S4
One contract across web and API
A shared package of TypeScript types and constants, with Zod validating forms on the way in.
Product experience
- Dark and light themes, a search bar in the header, and wishlist, account and cart one tap away.
- Featured drops and new arrivals carry discount and “new” badges with quick view.
- Orders are tracked on a timeline from placement to delivery.

