Ekaabo oo, Oro yii gun die, sugbon te eti re sile go gbo mhi!
- Project Overview
- Architecture
- Monorepo Journey
- Setup Instructions
- Available Commands
- Technology Stack
- Project Structure
- Development Workflow
- Troubleshooting
Person fit ask: "On top single page app you run go do don do npm install react router, npm install gbasgbos
and many packages, see as package.json
long, monorepo too haba, wetin Vanilla js?"
Me: Hear me out o! I for use plain HTML and CSS but that one go be mess scatter for ground. Why? Because I decide say make I use Sanity for all the convenience wey e dey offer.
Real Talk: When Uthman wan change text, boom! E just work without am having to slide into my DMs dey talk say "How far Bola I need your help πππ"
Animation nko? No be me plain CSS and JS animations go kill! My mama still dey house o!
Monorepo? Bro, I want organization and I want npm run dev
to work without me having to manually cd
into both frontend
and cms
folders in different terminal tabs to do npm run dev
. That one na stress!
Either way, here is how the app dey go:
project-root/
βββ frontend/ # Contains the UI logic
βββ cms/ # Contains the CMS logic
βββ package.json # Monorepo configuration with npm workspaces
- Frontend: Contains all the UI logic and user interactions
- CMS: Contains the CMS logic - we use Sanity as our CMS of choice
- Root: The monorepo configuration that ties everything together
Why Sanity?
- I'm very familiar with it
- Their TypeScript integration na top notch
- Content management without wahala
Person fit ask: "But bro, why you no use Turbo repo? I don see am for plenty tutorial!"
Real Talk: Turbo repo na overkill for wetin we dey do! npm workspaces don give us 80% of wetin we need with 20% of the complexity. We no need all that caching and build orchestration wahala for portfolio website, infact all this package.jsons for just two pages is a whole lot, seems like overengineering looking from the outside, but if you sit down and reason the matter wella, una go know say nha condition make crayfish bend.
{
"workspaces": ["frontend", "cms"],
"scripts": {
"dev": "concurrently \"npm run dev --workspace=frontend\" \"npm run dev --workspace=cms\""
}
}
See how e sweet? One command npm run dev
and both frontend and cms go start together! No more running around different terminals like headless chicken (chai, nha me dey call myself chicken sha).
- concurrently: Make both apps run together with different colors for their logs (reason for choosing this is again I used it in the past)
- rimraf: Cross-platform way to delete
node_modules
(God punish windows sha!)
- Node.js (version 16 or higher) - npm workspaces need am!
- npm version 7+ (for workspaces support)
- Git
-
Clone the repository:
git clone [repo-url] cd uthman-portfolio
-
Install ALL dependencies with one command:
# This one command go install everything, frontend, and cms no stress and no sorrow. npm install # or you fit use our custom command npm run install:all
-
Set up environment variables:
# Most likely the ones from sanity bro (applicable to only the frotend sha)
-
Start development servers (The Sweet Part!):
# This one command go start BOTH frontend and cms together! npm run dev
Or if you wan start them separately:
npm run dev:frontend # Only React app npm run dev:cms # Only Sanity studio
npm run dev # Start both frontend and cms together
npm run dev:frontend # Start only React app
npm run dev:cms # Start only Sanity studio
npm run build # Build both apps for production
npm run build:frontend # Build only frontend
npm run build:cms # Build only cms
npm run install:all # Install all dependencies (same as npm install)
npm run install:frontend # Install only frontend dependencies
npm run install:cms # Install only cms dependencies
npm run clean # Delete ALL node_modules and reinstall everything
npm run fresh # Same as clean (Pick your poison bro)
npm run clean:all # Delete ALL node_modules but don't reinstall
npm run clean:frontend # Clean only frontend
npm run clean:cms # Clean only cms
npm run clean:root # Clean only root
Why we need clean commands? Sometimes dependency go just dey misbehave and the only way na to delete everything start afresh (Something turbo taught me the fucking hard way)!
npm run lint # Run ESLint on all workspaces
npm run lint:frontend # Lint only frontend
npm run lint:cms # Lint only cms
npm run lint:fix # Auto-fix ESLint errors everywhere
npm run lint:fix:frontend # Auto-fix only frontend
npm run lint:fix:cms # Auto-fix only cms
- React Router Framework Mode - For building the UI and also getting some SSR benefits without the premium wahala of next.js
- TypeScript - Standard in big 2025
- Vite - Our odogwu on which this entire house is built on
- Tailwind CSS - Cos why I go dey create extra css file nha
- Sanity - Headless CMS for content management
- Sanity Studio - For content editing interface
- TypeScript - For type safety with Sanity schemas
- npm workspaces - For managing the monorepo (no Turbo needed!)
- concurrently - Run multiple commands at once with colored output
- rimraf - Cross-platform file deletion (works on Windows and Unix)
- ESLint - For code linting across all workspaces
- Prettier - For code formatting
uthman-portfolio/
βββ package.json # Root config with workspaces and scripts
βββ node_modules/ # Shared dependencies
βββ package-lock.json # Root lock file
βββ frontend/
β βββ app/
β β βββ components/
β β βββ routes/
β β βββ lib/ # Helper functions an all that type shit
β β βββ types.ts # would contain all the types from fetching from the sanity studio cms
β βββ public/
β
β
βββ cms/
β βββ schemaTypes/ #Contains all the defined schemas
β βββ sanity.config.ts
β βββ package.json # CMS-specific dependencies
β βββ package-lock.json # CMS lock file
βββ README.md
- Root package.json: Controls the entire monorepo with workspaces
- Individual package.json files: Each workspace get their own dependencies
- Shared node_modules: npm workspaces automatically link packages to avoid duplication
- Symlinks: Your workspaces dey link to each other through symlinks (like shortcuts)
# Morning setup
npm run dev # Start everything
# Code, code, code...
# Before commit
npm run lint:fix # Fix any linting issues
npm run build # Make sure everything builds fine
# Dependency issues?
npm run fresh # Nuclear option - delete everything and start over
# Only frontend get problem?
npm run clean:frontend && npm run install:frontend
# Only cms get wahala?
npm run clean:cms && npm run install:cms
# Add to frontend only
npm install lodash --workspace=frontend
# Add to cms only
npm install some-package --workspace=cms
# Add to root (development tools)
npm install -D some-dev-tool
"npm run dev no dey work!"
- Make sure you get Node 16+ and npm 7+
- Run
npm run fresh
to reset everything
"One workspace no dey start!"
- Check if that workspace get the script defined in their package.json
- Try run am individually:
npm run dev:frontend
ornpm run dev:cms
"Dependencies no dey install properly!"
- Clear everything:
npm run clean:all
- Install fresh:
npm run install:all
"I wan share code between frontend and cms!"
- Create a shared folder in root
- Use relative imports between workspaces
- Or create a separate workspace for shared utilities
That's basically it! 1 simple monorepo setup rules them all. The npm workspaces approach fit look simple but e dey very powerful and no get unnecessary complexity wey Turbo repo go bring.
Why This Setup Sweet:
- Single command development:
npm run dev
start everything - Granular control: You fit work on individual parts when needed
- Clean template:
npm run clean:all
give you fresh template to share - Cross-platform: Everything work for Windows, Mac, and Linux
- Future-proof: Easy to add more workspaces if Uthman wan expand
The architecture fit look like overkill but trust me, it's for the best. When I don cook am finish, you go appreciate the organization!
Developer: Omo, it's Bolarinwa on the Keyboard,
Version: 1.0.0 (definitely more avenues may pop up where uthman want to cook like mad)
Monorepo Configuration: npm workspaces with concurrently and rimraf for maximum developer experience, Oshamo π