Marrowtone — Premium Acoustic Guitar E-Commerce
A modern full-stack guitar shop built with the T3 Stack (Next.js, tRPC, TypeScript, Prisma, Tailwind CSS). Designed for performance, type safety, and a premium shopping experience.
Why I Built This
I wanted to build something that demonstrates real-world full-stack development skills — not just tutorials, but a complete, polished application with:
- Type-safe API communication between client and server via tRPC
- Complex filtering logic with multiple filter types, price range slider, search, and sorting
- Performance optimizations including debounced inputs to prevent excessive database queries
- Beautiful, distinctive design with a custom wood-themed dark mode aesthetic
- Production-ready architecture with proper separation of concerns
Guitar shops are personal — they're about craftsmanship, tone, and legacy. I built Marrowtone to showcase how modern web development can honor that same attention to detail.
Key Features
- Advanced Filtering: Filter by body shape, wood type, electronics, price range, and in-stock status
- Debounced Search: Real-time search with debouncing to optimize performance
- Sorting: Sort by price (low/high), rating, name, or newest
- Dark Mode: Custom wood-themed dark palette (walnut, mahogany, honey amber)
- Authentication: Secure user authentication via NextAuth.js
- SEO Ready: Server-side rendering with proper metadata support
- Responsive Design: Mobile-first with breakpoints for all devices
Architecture Highlights
Type-Safe APIs with tRPC
All API routes are type-safe — the frontend knows exactly what the backend returns:
// Server (tRPC router)
export const shopRouter = createTRPCRouter({
getQueryPayload: publicProcedure
.input(z.object({ searchParams: z.union([z.string(), z.record(...)])}))
.query(({ input }): ShopQueryPayload => { ... })
});
// Client (type-safe hooks)
const { data } = api.shop.getQueryPayload.useQuery({ searchParams: window.location.search });
Advanced Filtering Logic
The filtering system parses URL search params, applies filters server-side, and returns optimized Prisma queries — all types preserved end-to-end.
Custom Design System
Built on Tailwind CSS 4 with CSS variables and a custom wood palette:
--wood-950: oklch(0.12 0.01 35); /* deep studio background */
--wood-900: oklch(0.18 0.025 38); /* dark walnut */
--wood-500: oklch(0.56 0.055 58); /* honey / amber highlight */
--wood-300: oklch(0.74 0.035 55); /* soft warm text */
Why It's Good (For Employers)
- Cutting-Edge Stack: Next.js 15, React 19, tRPC v11 — you're working with the latest, most performant tools
- Type Safety End-to-End: From database to API to UI, everything is typed — fewer bugs, better DX
- Performance-First Mindset: Debounced inputs, SSR, proper caching — this isn't a demo, it's production thinking
- Design System Fluency: Custom themes, CSS variables, Tailwind 4 — demonstrates deep CSS knowledge
- Full-Stack Breadth: Database design, API architecture, authentication, UI — you understand the complete picture
Project Structure
src/
├── app/ # Next.js App Router pages
│ ├── _components/ # Shared page components
│ ├── shop/ # Guitar shop with filtering
│ ├── guitar/[id]/ # Individual guitar details
│ ├── builder/ # Custom guitar builder
│ └── api/ # API routes (tRPC, auth)
├── components/ # UI components
│ ├── ui/shadcn/ # Radix UI primitives
│ └── cards/ # Guitar cards
├── lib/ # Utilities & hooks
│ └── hooks/use-shop/ # Shop filtering logic
├── server/ # Backend
│ ├── api/routers/ # tRPC routers
│ ├── auth/ # NextAuth config
│ └── db.ts # Prisma client
└── styles/ # Global styles
Getting Started
# Install dependencies
npm install
# Set up database
npm run db:migrate
# Generate Prisma client
npm run db:generate
# Start development server
npm run dev
Environment Variables
Create a .env file with:
DATABASE_URL="postgresql://..."
NEXTAUTH_SECRET="your-secret"
NEXTAUTH_URL="http://localhost:3000"
License
MIT





