Dumroad is a modern, multi-tenant digital marketplace built with a powerful stack including Next.js, Payload CMS, and tRPC. It provides a platform for creators to sell digital products, with seamless payment integration using Stripe.
- Multi-tenancy: Each tenant has their own isolated data, allowing for multiple vendors to operate on the same platform.
- Digital Product Sales: Easily upload and sell digital products.
- Stripe Integration: Secure and reliable payment processing with Stripe, including webhook support for real-time updates.
- Authentication: Robust authentication system for users and tenants.
- Payload CMS: Powerful and flexible content management with a rich text editor and custom collections.
- tRPC: End-to-end typesafe APIs for a seamless development experience.
- Shadcn UI: Beautifully designed and accessible UI components.
- Framework: Next.js
- CMS: Payload CMS
- API: tRPC
- Database: MongoDB
- Styling: Tailwind CSS
- UI Components: Shadcn UI
- Payments: Stripe
- Schema Validation: Zod
- State Management: Zustand
-
Clone the repository:
git clone https://github.com/rit3sh-x/dumroad.git cd dumroad -
Install dependencies:
bun install
-
Set up environment variables:
Create a
.envfile by copying the example:cp .env.example .env
Update the
.envfile with your credentials:PAYLOAD_CONFIG_PATH=src/payload.config.ts PAYLOAD_SECRET=your-payload-secret DATABASE_URI=your-mongodb-uri NEXT_PUBLIC_APP_URL=http://localhost:3000 STRIPE_SECRET_KEY=your-stripe-secret-key STRIPE_WEBHOOK_KEY=your-stripe-webhook-secret
-
Start the development server:
bun run dev
-
Seed the database (optional):
To populate the database with initial data, run:
bun run db:seed
The application will be available at
http://localhost:3000.
dev: Starts the development server.build: Creates a production build.start: Starts the production server.lint: Lints the codebase.generate:types: Generates types from your Payload configuration.db:fresh: Drops the database and runs migrations.db:seed: Seeds the database with initial data.generate:importmap: Generates an import map for the Payload admin UI.
The project is organized into the following main directories:
src/app: Contains the Next.js application routes and layouts.src/collections: Defines the data models (collections) for Payload CMS.src/components: Shared UI components.src/hooks: Custom React hooks.src/lib: Utility functions and libraries.src/modules: Contains the core business logic for different features.src/trpc: tRPC server and client configuration.public: Static assets.
Dumroad is architected as a modular, full-stack application using Next.js for the frontend, Payload CMS for content and data management, tRPC for type-safe API communication, and Stripe for payments. Here’s how the main parts of the codebase work together:
The application loads environment variables from .env to configure connections to MongoDB, Stripe, and Payload CMS. The PAYLOAD_CONFIG_PATH points to the main Payload configuration in src/payload.config.ts, which defines collections, authentication, and admin UI settings.
-
Frontend (Next.js):
- Located in
src/app, the frontend uses Next.js app directory routing. Pages and layouts are organized by feature (e.g.,(auth),(home),(library),(tenants)). - UI components are in
src/componentsandsrc/components/ui, using Shadcn UI and Tailwind CSS for styling. - Custom React hooks in
src/hooksprovide reusable logic, such as device detection (use-mobile).
- Located in
-
Backend & API:
- tRPC is set up in
src/trpcto provide end-to-end type-safe APIs between the frontend and backend. Procedures are organized by feature insrc/trpc/routers. - The business logic for each feature (auth, checkout, products, tenants, etc.) is encapsulated in
src/modules, with clear separation between server logic, UI, and types. - Payload CMS collections are defined in
src/collections, describing the data models for users, products, orders, reviews, etc.
- tRPC is set up in
-
Payments:
- Stripe integration is handled in
src/lib/stripe.tsand related modules. Webhooks are managed insrc/app/(payload)/api/stripeandsrc/app/(payload)/api/stripe/webhooks.
- Stripe integration is handled in
- User requests (e.g., sign in, view products, checkout) are routed through Next.js pages and handled by React components.
- API calls are made via tRPC, which invokes server-side procedures in
src/modulesfor business logic (e.g., authentication, product queries, order creation). - Database operations are performed using the Payload CMS API, which interacts with MongoDB based on the collection definitions in
src/collections. - Payments are processed via Stripe, with webhook events updating order statuses in the database.
The tenants module and collection ensure that each vendor’s data is isolated. Middleware and server logic enforce tenant boundaries, so users and products are always scoped to the correct tenant.
Utility functions in src/lib support authentication, access control, and other cross-cutting concerns. The modular structure makes it easy to add new features or collections by following the established patterns in src/modules and src/collections.
Payload CMS provides an admin UI (configured in src/payload.config.ts) for managing collections, users, and content. Admins and vendors can use this interface to manage products, orders, and more.
Contributions are welcome! Please open an issue or submit a pull request for any changes.
This project is licensed under the MIT License.