A monorepo for the PrizeCart Shopify app, featuring a Node.js API backend and React frontend with shared TypeScript types.
prizecart/
├── api/ # Node.js + Express API backend
├── app/ # React frontend application
├── shared/ # Shared TypeScript types and utilities
├── docs/ # Project documentation
└── package.json # Root workspace configuration
- Node.js >= 18.0.0
- npm >= 8.0.0
# Install all dependencies across workspaces
npm run install:all
# Or install individually
npm install
npm --prefix api install
npm --prefix app install
npm --prefix shared install# Start both API and app in development mode
npm run dev
# Start only the API
npm run dev:api
# Start only the app
npm run dev:app# Build all packages
npm run build
# Build specific packages
npm run build:api
npm run build:app- Port: 3888 (default)
- Tech Stack: Node.js, Express, TypeScript
- Key Features:
- Shopify OAuth integration
- Webhook handling
- Prize draw logic
- JWT authentication
- Port: 3000 (default)
- Tech Stack: React, TypeScript
- Key Features:
- Customer prize draw interface
- Prize claim form
- Responsive design
- Purpose: TypeScript type definitions shared between API and app
- Key Exports:
- Data models (Merchant, Customer, Prize, Order, etc.)
- API request/response types
- Utility types and interfaces
- Express type augmentations
The monorepo uses TypeScript path mapping to share types between packages:
import type { DrawRequest, DrawResponse } from "@prizecart/shared";
// In any file, import shared types
import { Customer, Merchant, Prize } from "@prizecart/shared";User,Merchant,CustomerPrize,Order,DrawSession,ClaimProduct,ShippingAddress
DrawRequest,DrawResponseClaimRequest,MerchantInstallRequestApiResponse<T>,JWTPayload
Environment,PrizeCategory,UserRoleAppConfig,DatabaseConfig,ShopifyConfigPaginationParams,PaginatedResponse<T>
- Adding New Types: Add them to
shared/types/and export fromshared/index.ts - API Development: Use shared types for request/response validation
- Frontend Development: Import shared types for component props and API calls
- Type Safety: All packages benefit from shared type definitions
- Code Quality: All code is automatically linted and formatted through pre-commit hooks
Create .env files in the api/ directory:
# api/.env
PORT=3888
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/prizecart
JWT_SECRET=your-jwt-secret
SHOPIFY_API_KEY=your-shopify-api-key
SHOPIFY_API_SECRET=your-shopify-api-secret
ALLOWED_CORS_DOMAINS=localhost:3000npm run dev- Start both API and appnpm run build- Build all packagesnpm run clean- Clean all build artifactsnpm run install:all- Install dependencies for all workspaces
npm --prefix api run dev- Start API in development modenpm --prefix api run build- Build APInpm --prefix api run start- Start production API
npm --prefix app run start- Start React appnpm --prefix app run build- Build React appnpm --prefix app run test- Run tests
- Make changes to shared types in
shared/directory - Update API and app to use new shared types
- Ensure type safety across all packages
- Test both API and app functionality
If you encounter type resolution issues:
- Ensure all packages are installed:
npm run install:all - Rebuild shared package:
npm --prefix shared run build - Restart TypeScript language server in your IDE
If builds fail:
- Clean all build artifacts:
npm run clean - Reinstall dependencies:
npm run install:all - Rebuild packages:
npm run build
This project uses ESLint with Antfu's configuration for consistent code formatting and linting across the entire monorepo. The setup includes automatic formatting, pre-commit hooks, and environment-specific rules.
The project uses a modern flat config ESLint setup (eslint.config.js) with:
- Antfu's ESLint Config: Base configuration with TypeScript and React support
- Next.js Integration: Specific rules for Next.js best practices and core web vitals
- Custom Rules: Project-specific preferences including double quotes, semicolons, and 2-space indentation
- Environment-Specific Rules: Different rule sets for frontend (
app/), backend (api/), and shared (shared/) code
Run these commands from the project root:
# Lint all files in the monorepo
npm run lint
# Automatically fix all auto-fixable linting issues
npm run lint:fix
# Lint only backend (API) files
npm run lint:api
# Lint only frontend (app) files
npm run lint:app
# Lint only shared files
npm run lint:shared
# Lint only staged files (used by pre-commit hook)
npm run lint:stagedThe project uses Husky to enforce code quality before commits:
- Automatic Setup: Pre-commit hooks are automatically installed when you run
npm install - Staged File Linting: Only files staged for commit are linted (fast and efficient)
- Auto-fixing: Fixable issues are automatically corrected before commit
- Commit Blocking: Commits are blocked if there are unfixable linting errors
- Clear Feedback: The hook provides clear output about any issues found
The pre-commit hook runs lint-staged, which applies eslint --fix to all staged JavaScript and TypeScript files.
- Install ESLint Extension: Install the official ESLint extension from the VS Code marketplace
- Auto-fix on Save: The project includes VS Code settings for automatic fixing on save
- Flat Config Support: Ensure you're using ESLint extension v2.4.0+ for flat config support
For other editors, ensure your ESLint plugin supports:
- Flat config format (
eslint.config.js) - Auto-fix on save functionality
- TypeScript and React file support