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