Skip to content

Latest commit

Β 

History

180 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cape Cod World Monorepo

Please Note this project is currently in development and still has some rough edges. Use at your own risk.

A production-ready monorepo combining a TanStack React frontend with Sanity Studio, powered by Vite+.

This project is a custom fork of the original Santan Monorepo, which can be found here.

TypeScript Vite+ Node.js


πŸ“‹ Table of Contents


Overview

This monorepo combines a React frontend and Sanity Studio into a single, optimized workspace with:

βœ… Shared type system - Auto-generated Sanity types used across both apps
βœ… Vite+ task runner - Workspace-aware vp run for build and dev
βœ… Production-ready - Properly configured for deployment
βœ… Type-safe - Full TypeScript support throughout
βœ… Hot reloading - Fast development experience

Tech Stack

Frontend (apps/frontend)

  • React 19
  • TanStack Router & Query
  • Vite+ (Vite 8, Oxlint, Oxfmt, Vitest)
  • Sanity Client
  • Tailwind CSS

Studio (apps/studio)

  • Sanity Studio 5
  • Custom schema types
  • Document preview

Shared (packages/shared)

  • Auto-generated Sanity types
  • Shared utilities
  • Type-safe enums

Quick Start

Prerequisites

  • Node.js β‰₯ 24
  • npm (comes with Node.js)
  • Sanity account with a configured project

1. Clone and Install

cd /path/to/santan-monorepo
npm install

2. Configure Environment

Frontend:

cp apps/frontend/.env.example apps/frontend/.env.local

Edit apps/frontend/.env.local:

VITE_SANITY_PROJECT_ID=your_project_id
VITE_SANITY_DATASET=production
VITE_SANITY_API_VERSION=2024-01-01
SESSION_SECRET=generate_a_random_secret_here
# Contact form (see docs/CONTACT_FORM.md)
DATABASE_URL=your_neon_connection_string
ZOHO_SMTP_USER=you@yourdomain.com
ZOHO_SMTP_PASS=your_zoho_app_password

Studio:

cp apps/studio/.env.example apps/studio/.env.local

Edit apps/studio/.env.local:

SANITY_STUDIO_PROJECT_ID=your_project_id
SANITY_STUDIO_DATASET=production

3. Start Development

npm run dev

This starts:


Project Structure

santan-monorepo/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ frontend/              # React frontend
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ routes/       # TanStack Router routes
β”‚   β”‚   β”‚   β”œβ”€β”€ components/   # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ sanity/       # Sanity queries and loaders
β”‚   β”‚   β”‚   └── types/        # Frontend-specific types
β”‚   β”‚   β”œβ”€β”€ .env.local        # Environment variables (not in git)
β”‚   β”‚   └── package.json      # @santan/frontend
β”‚   β”‚
β”‚   └── studio/                # Sanity Studio
β”‚       β”œβ”€β”€ src/
β”‚       β”‚   β”œβ”€β”€ schemaTypes/  # Content schemas
β”‚       β”‚   β”œβ”€β”€ structure/    # Studio structure
β”‚       β”‚   └── scripts/      # Type generation scripts
β”‚       β”œβ”€β”€ .env.local        # Environment variables (not in git)
β”‚       └── package.json      # @santan/studio
β”‚
β”œβ”€β”€ packages/
β”‚   └── shared/                # Shared package (auto-generated types)
β”‚       β”œβ”€β”€ src/
β”‚       β”‚   β”œβ”€β”€ types/
β”‚       β”‚   β”‚   β”œβ”€β”€ sanity.types.ts       # Generated Sanity types
β”‚       β”‚   β”‚   └── sanityTypeLiterals.ts # Type literal enums
β”‚       β”‚   └── index.ts      # Main export
β”‚       β”œβ”€β”€ dist/             # Compiled output (generated)
β”‚       └── package.json      # @santan/shared
β”‚
β”œβ”€β”€ vite.config.ts             # Vite+ lint, format, test, and task config
β”œβ”€β”€ package.json               # Root package with workspaces
β”œβ”€β”€ README.md                  # This file
└── docs/
    β”œβ”€β”€ TYPE_MIGRATION.md      # Type generation guide
    └── PRODUCTION_READY.md    # Production deployment guide

Development

Run All Apps

npm run dev

Starts all workspaces with hot reloading:

  • Frontend dev server
  • Studio dev server
  • Shared package in watch mode (auto-rebuilds on changes)

Run Individual Apps

# Frontend only
vp dev

# Studio only
vp run @santan/studio#dev

# Shared package only (watch mode)
vp run @santan/shared#dev

Working with Shared Types

The @santan/shared package contains auto-generated Sanity types:

// Import in Frontend or Studio
import { Post, Category, Author, sanityTypeLiterals } from '@santan/shared/types';

// Type-safe document checking
if (doc._type === sanityTypeLiterals.post) {
	// TypeScript knows doc is Post type
	console.log(doc.title, doc.slug);
}

Production

Building for Production

npm run build

This builds all packages in the correct order:

  1. Shared package β†’ Compiles TypeScript to JavaScript
  2. Studio β†’ Builds Sanity Studio (using shared types)
  3. Frontend β†’ Builds React app (using shared types)

Build Output

  • Frontend: apps/frontend/.output/ (Nitro/Vite output)
  • Studio: apps/studio/dist/ (Sanity Studio build)
  • Shared: packages/shared/dist/ (Compiled types)

Deployment

Frontend (Vercel/Netlify):

  • Root directory: apps/frontend
  • Build command: npm run build
  • Output directory: apps/frontend/.output or apps/frontend/dist

Studio (Sanity):

cd apps/studio
npm run deploy

Or from root:

npm run deploy --workspace=@santan/studio

See packages/shared/PRODUCTION_READY.md for complete deployment guide.


Type Generation

When to Regenerate Types

Run type generation whenever you:

  • Add a new document type in Sanity Studio
  • Modify existing schemas
  • Change field definitions
  • Update portable text configurations

Generate Types

cd apps/studio
npm run generate-types

What this does:

  1. Extracts Sanity schema β†’ schema.json
  2. Generates TypeScript types β†’ packages/shared/src/types/sanity.types.ts
  3. Extracts type literals β†’ packages/shared/src/types/sanityTypeLiterals.ts

The shared package automatically rebuilds (if dev mode is running), making types instantly available to both Frontend and Studio.

See TYPE_MIGRATION.md for detailed type generation workflow.


Available Commands

Root Commands

Command Description
vp run -r --parallel dev / npm run dev Start all apps in development mode
vp run -r build / npm run build Build all apps for production
vp run -r type-check Type check all packages
vp check Format, lint, and type-check (Oxfmt + Oxlint)
vp lint / npm run lint Lint all packages with Oxlint
vp fmt --write / npm run format Format code with Oxfmt
npm run clean Clean build artifacts

Workspace Commands

Run commands in specific packages:

# Pattern
vp run @santan/<package>#<task>

# Examples
vp dev
vp run @santan/studio#dev
vp run @santan/shared#type-check

Documentation


Troubleshooting

Port Already in Use

If ports 3000 or 3333 are in use:

# Kill processes on specific ports
lsof -ti:3000 | xargs kill -9
lsof -ti:3333 | xargs kill -9

# Or kill all dev servers
pkill -f "npm run dev"

Frontend Can't Connect to Sanity

Check your .env.local files:

  • βœ… VITE_SANITY_PROJECT_ID matches your Sanity project
  • βœ… VITE_SANITY_DATASET is correct (usually "production")
  • βœ… VITE_SANITY_API_VERSION is valid

Types Not Updating

  1. Regenerate types:

    cd apps/studio
    npm run generate-types
  2. If dev mode is running, shared package should auto-rebuild

  3. Otherwise, manually build:

    cd packages/shared
    npm run build
  4. Restart TypeScript server in your IDE:

    • VS Code: CMD+Shift+P β†’ "TypeScript: Restart TS Server"
    • WebStorm: Should auto-reload

"Cannot find module" Errors

Ensure dependencies are installed:

npm install

If issues persist, clean and reinstall:

npm run clean
rm -rf node_modules apps/*/node_modules packages/*/node_modules
npm install

Build Errors in Production

Ensure the shared package is built before other packages:

vp run @santan/shared#build
vp run -r build

vp run -r build already includes @santan/shared. For a frontend-only deploy, use vp run --filter @santan/shared --filter @santan/frontend build.


Benefits of This Monorepo

For Development

βœ… Single clone - Get frontend and studio together
βœ… Shared types - Auto-generated, always in sync
βœ… Fast builds - Vite+ task runner across workspaces
βœ… Hot reloading - Changes reflect immediately
βœ… Type safety - Full TypeScript support

For Production

βœ… Optimized builds - Only rebuild what changed
βœ… Type-safe deployments - Compile-time type checking
βœ… Atomic commits - Change frontend and studio together
βœ… Single source of truth - One repo, one package.json

For Teams

βœ… Easier onboarding - Clone once, everything works
βœ… Consistent tooling - Same linting, formatting, testing
βœ… Simplified CI/CD - One pipeline for everything
βœ… Better collaboration - See all changes in one place


Support & Resources


License

MIT


Status: βœ… Production Ready
Last Updated: October 30, 2025

About

The New And Improved Cape Cod World Site

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages