From hypervibe
Internal helper to convert a single Next.js project into a Turborepo monorepo. Idempotent - if the project is already a monorepo (apps/web/ exists), returns immediately. Moves the existing project into apps/web/, creates root package.json with workspaces, pnpm-workspace.yaml, turbo.json, and adds turbo as a dev dependency. Optionally extracts a shared packages/db package if a Drizzle DB is detected. Updates imports in apps/web accordingly. Triggered by /add-automation. Not meant to be invoked directly by users.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hypervibe:_convert-to-turborepoThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Detect the user's language from their messages and ALWAYS reply in that language (default: English). This applies to every user-facing message: questions, progress, confirmations, summaries, errors.
Convert a single Next.js project into a Turborepo monorepo. Idempotent - if already a monorepo, return immediately.
test -d apps/web && echo "already-monorepo" || echo "single-app"
If already-monorepo, tell the user:
The project is already a Turborepo monorepo. There is nothing for me to do.
Return control to the caller immediately. Skip all remaining steps.
If single-app, continue to Step 2.
Read the current project name from package.json:
node -e "process.stdout.write(require('./package.json').name)"
Detect if a Drizzle DB is configured:
test -f drizzle.config.ts -o -f drizzle.config.js && echo "has-db" || echo "no-db"
Tell the user:
I am going to convert your project into a Turborepo monorepo: the current code moves to
apps/web/, with a new rootpackage.json+pnpm-workspace.yaml+turbo.json, and turbo added as a devDep, plus the Drizzle DB extracted intopackages/db/.⚠️ Commit your work in progress first - this operation moves a lot of files and is hard to revert.
Ready to go? (reply
yesto continue)
Wait for confirmation. Don't start without it.
git status --porcelain
If there are uncommitted changes, refuse:
❌ You have uncommitted changes. Commit or stash them first, then re-run
/add-automation.
Return to caller without doing anything.
mkdir -p apps/web
Move everything except apps/, .git, node_modules, and lock files. Use git mv to preserve history (fall back to mv if git mv fails on ignored files).
shopt -s dotglob nullglob
for item in *; do
case "$item" in
apps|.git|node_modules|pnpm-lock.yaml|package-lock.json|yarn.lock) continue ;;
*) git mv "$item" "apps/web/$item" ;;
esac
done
test -f pnpm-lock.yaml && mv pnpm-lock.yaml apps/web/pnpm-lock.yaml
rm -rf node_modules # we'll reinstall at the end
cat > package.json <<'EOF'
{
"name": "<project-name>-monorepo",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"lint": "turbo lint"
},
"devDependencies": {
"turbo": "^2.0.0"
},
"packageManager": "[email protected]"
}
EOF
Replace <project-name> with the actual name from the original package.json.
packages:
- "apps/*"
- "packages/*"
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {}
}
}
Skip this step if no-db.
If has-db:
mkdir -p packages/db
Move the Drizzle config and schema (the git mv renames db/ to packages/db/src/, so packages/db/src must not pre-exist):
git mv apps/web/drizzle.config.ts packages/db/drizzle.config.ts
git mv apps/web/src/server/db packages/db/src
Create packages/db/package.json:
{
"name": "@<project-name>/db",
"version": "0.0.0",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio"
}
}
Create packages/db/tsconfig.json:
{
"extends": "../../apps/web/tsconfig.json",
"include": ["src/**/*", "drizzle.config.ts"]
}
Make sure packages/db/src/index.ts exists and re-exports the Drizzle client:
export * from "./schema";
// Adjust depending on what was in src/server/db originally
Find all files in apps/web that import from ~/server/db or @/server/db and rewrite them to @<project-name>/db:
cd apps/web
grep -rln "from \"~/server/db" src/ | xargs sed -i 's|from "~/server/db|from "@<project-name>/db|g'
grep -rln "from \"@/server/db" src/ | xargs sed -i 's|from "@/server/db|from "@<project-name>/db|g'
Be careful: only rewrite the exact ~/server/db and @/server/db prefixes, not other things.
Add to apps/web/package.json:
{
"dependencies": {
"@<project-name>/db": "workspace:*"
}
}
pnpm install
This will create a fresh pnpm-lock.yaml at the root and install everything across the workspace.
pnpm dev --filter=web
Wait a few seconds. If Next.js starts on port 3000 without errors, kill it (Ctrl+C). The conversion is successful.
If it errors:
rm -rf node_modules apps/*/node_modules packages/*/node_modules pnpm-lock.yaml && pnpm installgit add .
git commit -m "refactor: convert to Turborepo monorepo"
⚠️ Don't push automatically - let the caller (/add-automation) decide when to push.
Tell the user:
✅ Conversion to a Turborepo monorepo complete. Your app now lives in
apps/web/, and your shared DB inpackages/db/.New commands:
pnpm dev(all apps),pnpm dev --filter=web(just the frontend),pnpm build.Commit made locally, not pushed - the caller will decide when to push.
Return control to the calling skill (/add-automation).
npx claudepluginhub flavien-ia/hypervibe-harness --plugin hypervibeConfigures Next.js inside a monorepo with shared packages and Turborepo task orchestration. Useful for building multiple Next.js apps sharing UI, config, or types.
Set up and optimize monorepos with Turborepo, Nx, pnpm workspaces for shared code, efficient builds, dependency management, and CI/CD.
Guides Turborepo monorepo management: workspace creation, turbo.json task configuration, Next.js/NestJS app setup, Vitest/Jest test pipelines, CI/CD workflows, remote caching, and build optimization for TypeScript/JavaScript projects.