SanTan
Tanstack Start with Sanity Visual Editing
Santan Monorepo
A production-ready monorepo combining a React frontend with Sanity Studio, powered by Turborepo.
📋 Table of Contents
- Overview
- Quick Start
- Project Structure
- Development
- Production
- Type Generation
- Available Commands
- Documentation
- Troubleshooting
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
✅ Turborepo caching - Lightning-fast builds with intelligent caching
✅ 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 7
- Sanity Client
- Tailwind CSS
Studio (apps/studio)
- Sanity Studio 4
- Custom schema types
- Document preview
Shared (packages/shared)
- Auto-generated Sanity types
- Shared utilities
- Type-safe enums
Quick Start
Prerequisites
- Node.js ≥ 18
- npm (comes with Node.js)
- Sanity account with a configured project
1. Clone and Install
cd /path/to/santan-monorepo
npm install2. Configure Environment
Frontend:
cp apps/frontend/.env.example apps/frontend/.env.localEdit 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_hereStudio:
cp apps/studio/.env.example apps/studio/.env.localEdit apps/studio/.env.local:
SANITY_STUDIO_PROJECT_ID=your_project_id
SANITY_STUDIO_DATASET=production3. Start Development
npm run devThis starts:
- 🌐 Frontend at http://localhost:3000
- 🎨 Studio at http://localhost:3333
- 🔧 Shared package in watch mode (auto-recompiles on changes)
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
│
├── turbo.json # Turborepo configuration
├── package.json # Root package with workspaces
├── README.md # This file
└── docs/
├── TYPE_MIGRATION.md # Type generation guide
└── PRODUCTION_READY.md # Production deployment guideDevelopment
Run All Apps
npm run devStarts 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
npm run dev --workspace=@santan/frontend
# Studio only
npm run dev --workspace=@santan/studio
# Shared package only (watch mode)
npm run dev --workspace=@santan/sharedWorking 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 buildThis builds all packages in the correct order:
- Shared package → Compiles TypeScript to JavaScript
- Studio → Builds Sanity Studio (using shared types)
- 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/.outputorapps/frontend/dist
Studio (Sanity):
cd apps/studio
npm run deployOr from root:
npm run deploy --workspace=@santan/studioSee 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-typesWhat this does:
- Extracts Sanity schema →
schema.json - Generates TypeScript types →
packages/shared/src/types/sanity.types.ts - 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 |
|---|---|
npm run dev | Start all apps in development mode |
npm run build | Build all apps for production |
npm run type-check | Type check all packages |
npm run lint | Lint all packages |
npm run format | Format code with Prettier |
npm run clean | Clean build artifacts |
Workspace Commands
Run commands in specific packages:
# Pattern
npm run <command> --workspace=@santan/<package>
# Examples
npm run dev --workspace=@santan/frontend
npm run build --workspace=@santan/studio
npm run type-check --workspace=@santan/sharedDocumentation
- TYPE_MIGRATION.md - Complete type generation and migration guide
- packages/shared/TYPES_README.md - Detailed shared package documentation
- packages/shared/PRODUCTION_READY.md - Production deployment guide
- GETTING_STARTED.md - Detailed setup instructions
- docs/FULLSLUG_SYSTEM.md - Sanity fullSlug system for hierarchical URLs
- docs/INDEX.md - Complete documentation index
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_IDmatches your Sanity project - ✅
VITE_SANITY_DATASETis correct (usually "production") - ✅
VITE_SANITY_API_VERSIONis valid
Types Not Updating
Regenerate types:
cd apps/studio npm run generate-typesIf dev mode is running, shared package should auto-rebuild
Otherwise, manually build:
cd packages/shared npm run buildRestart TypeScript server in your IDE:
- VS Code:
CMD+Shift+P→ "TypeScript: Restart TS Server" - WebStorm: Should auto-reload
- VS Code:
"Cannot find module" Errors
Ensure dependencies are installed:
npm installIf issues persist, clean and reinstall:
npm run clean
rm -rf node_modules apps/*/node_modules packages/*/node_modules
npm installBuild Errors in Production
Ensure the shared package is built before other packages:
cd packages/shared && npm run build
cd ../..
npm run buildTurborepo should handle this automatically with the ^build dependency.
Benefits of This Monorepo
For Development
✅ Single clone - Get frontend and studio together
✅ Shared types - Auto-generated, always in sync
✅ Fast builds - Turborepo caches everything
✅ 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
- Turborepo: https://turbo.build/repo/docs
- Sanity: https://www.sanity.io/docs
- TanStack Router: https://tanstack.com/router
- Vite: https://vitejs.dev
Powering ShareScan.io: https://sharescan.io
License
MIT
Status: ✅ Production Ready
Last Updated: October 30, 2025