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