_convert-to-turborepo
Skill52 starsChanged todayApache-2.0View on GitHub
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.
- Reads credentials
- Deletes or force-pushes
- Installs packages
1 other project uses a version of this.
Adopted by
Most recently taken up by
- flavien-ia/hypervibe-craftword for word, first seen Oct 25, 2026
Other versions1 project uses a version of this.
Word for word · 1
- flavien-ia/hypervibe-craft★ 52100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository89 other files it gives its agents.
- accessibilitySkill
- add-2faSkill
- add-agent-dashboardSkill
- add-aiSkill
- add-analyticsSkill
- add-authSkill
- add-automationSkill
- add-backup-dbSkill
- add-collabSkill
- add-cronSkill
- add-dark-modeSkill
- add-dbSkill
- add-domainSkill
- add-emailSkill
- add-github-authSkill
- add-google-authSkill
- add-i18nSkill
- _add-keyringSkill
- add-mapSkill
- add-notification-centerSkill
- add-push-notificationSkill
- add-pwaSkill
- add-roleSkill
- add-routineSkill
- add-storageSkill
- add-stripeSkill
- add-testSkill
- bootstrapSkill
- _check-depsSkill
- cleanSkill
- _collect-secretSkill
- _create-agentSkill
- _create-cloudflare-workerSkill
- _create-contact-pageSkill
- _create-render-workerSkill
- _create-routineSkill
- _create-workflowSkill
- delete-projectSkill
- _detect-project-rootSkill
- _dns-brevoSkill
- _dns-cloudflareSkill
- _dns-gandiSkill
- _dns-godaddy-manualSkill
- _dns-hostingerSkill
- _dns-infomaniak-manualSkill
- _dns-ionos-manualSkill
- _dns-lwsSkill
- _dns-namecheapSkill
- _dns-ovhSkill
- _dns-porkbunSkill
- _dns-resendSkill
- _dns-squarespace-manualSkill
- eco-auditSkill
- _ensure-aiSkill
- _ensure-vaultSkill
- _generate-secretSkill
- geoSkill
- _get-secretSkill
- gscSkill
- _hash-passwordSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 6 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 13
Use plain, non-technical business language.
- Distinctive: line 14
When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Very specific: line 27
If already-monorepo, tell the user:
- Very specific: line 32
If single-app, continue to Step 2.
- Very specific: line 36
Read the current project name from package.json:
- Distinctive: line 53
Wait for confirmation. Don't start without it.
- Distinctive: line 61
If there are uncommitted changes, refuse:
- Distinctive: line 72
Only the APPLICATION moves.
- Very specific: line 102
If a LEFT AT THE ROOT line names something the application needs (a local file it reads at run time), say so to the user and move it into …
- Very specific: line 196
Make sure packages/db/src/index.ts exists and re-exports the Drizzle client:
- Very specific: line 239
Wait a few seconds. If Next.js starts on port 3000 without errors, kill it (Ctrl+C).
- Distinctive: line 275
Wait for the confirmation, and pass it on to the caller: it pushes only once the setting is changed, then checks that the site still …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Convert to Turborepo - Internal helper
Communication
- Detect the user's language from the conversation (the user's own messages, anywhere in the session - not just this invocation: a bare slash command like
/bootstrapcarries no language signal by itself). If nothing in the conversation gives a signal, fall back to the OS locale (node -e "console.log(Intl.DateTimeFormat().resolvedOptions().locale)") before defaulting to English. ALWAYS reply in that language for every user-facing message: questions, progress, confirmations, summaries, errors - including any example text quoted in this skill, which is illustrative and must be translated, never sent verbatim. - Use plain, non-technical business language. Never expose internal script names (*.mjs) or jargon; describe actions in human terms.
- When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Show progress as a short natural-language checklist (in-progress and done states).
Convert a single Next.js project into a Turborepo monorepo. Idempotent - if already a monorepo, return immediately.
Step 1 - Idempotency check
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.
Step 2 - Capture state and warn the user
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<if has-db>, plus the Drizzle DB extracted intopackages/db/</if>. What belongs to the repository itself (its automations, the project's resource list, your project rules) stays where it is.⚠️ Commit your work in progress first - this operation moves a lot of files and is hard to revert. And one setting will have to change on Vercel before the next push: I will tell you which, at the end.
Ready to go? (reply
yesto continue)
Wait for confirmation. Don't start without it.
Step 3 - Verify clean working tree
git status --porcelainIf 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.
Step 4 - Move the project into apps/web/
mkdir -p apps/webOnly the APPLICATION moves. What belongs to the REPOSITORY stays at its root, because what reads it looks there and nowhere else:
.github/: the forge reads a repository's automations at its root only (deployment, scheduled tasks, checks). Moved, they would silently stop..hypervibe/: the project's resource manifest, one per repository, at its root. Moved, a second one would be born at the root, and each half would miss the other's resources.CLAUDE.mdand.claude/: the project's rules and settings, read from where the sessions open, the repository's root..git,.gitattributes, the lockfile (pnpm keeps a workspace's single lockfile at its root), and the files that tools read from the root of a workspace or look for upward from any folder (.npmrc,.nvmrc,.node-version,.tool-versions,.editorconfig,.vscode/)..gitignoreis copied, not moved: the root one keeps covering what stays at the root, and the copy keeps the application's own patterns (/.next/,/node_modules) meaning the same thing inapps/web/.
What git tracks moves with git mv (its history follows). The application's own untracked files (.env, .env.*, .vercel/) move with a plain mv: they belong to the application, and they never go through git. Anything else that git does not track stays where it is, and is named.
shopt -s dotglob nullglob
for item in *; do
case "$item" in
apps|packages|.git|.github|.hypervibe|.claude|CLAUDE.md|.gitattributes|.gitignore|.npmrc|.nvmrc|.node-version|.tool-versions|.editorconfig|.vscode|node_modules|pnpm-lock.yaml|package-lock.json|yarn.lock) continue ;;
esac
if git ls-files --error-unmatch -- "$item" >/dev/null 2>&1; then
git mv -- "$item" "apps/web/$item"
else
case "$item" in
.env|.env.*|.vercel) mv -- "$item" "apps/web/$item" ;;
*) echo "LEFT AT THE ROOT (not tracked by git): $item" ;;
esac
fi
done
shopt -u dotglob nullglob
test -f .gitignore && cp .gitignore apps/web/.gitignore
rm -rf node_modules # we'll reinstall at the endIf a LEFT AT THE ROOT line names something the application needs (a local file it reads at run time), say so to the user and move it into apps/web/ with a plain mv.
Step 5 - Create root package.json
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": "pnpm@9.0.0"
}
EOFReplace <project-name> with the actual name from the original package.json.
Step 6 - Create pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"Step 4 moved the app's own pnpm-workspace.yaml into apps/web/. pnpm only honours the file at the workspace root, and a nested one makes pnpm treat apps/web as a separate workspace whenever a command runs from there. So if apps/web/pnpm-workspace.yaml exists: copy its other top-level blocks (allowBuilds:, overrides:) below packages: in the root file, then git rm apps/web/pnpm-workspace.yaml. Keep overrides: exactly as it is: it holds the security floors written by /bootstrap, and the lockfile must keep recording them. Never move them into a package.json (pnpm.overrides): pnpm 11+ ignores that field while Vercel's pnpm 10 reads it, and the deploy fails with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH.
Step 7 - Create turbo.json
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {}
}
}Step 8 - Extract DB to packages/db/ (if has-db)
Skip this step if no-db.
If has-db:
mkdir -p packages/dbMove 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/srcCreate 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 originally8a - Update imports in apps/web
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.
8b - Add the dependency in apps/web/package.json
Add to apps/web/package.json:
{
"dependencies": {
"@<project-name>/db": "workspace:*"
}
}Step 9 - Reinstall dependencies
pnpm installThis rewrites the root pnpm-lock.yaml for the workspace and installs everything across it.
Step 10 - Verify the conversion
pnpm dev --filter=webWait a few seconds. If Next.js starts on port 3000 without errors, kill it (Ctrl+C). The conversion is successful.
If it errors:
- Module not found errors → an import wasn't rewritten in Step 8a. Find and fix.
- Lockfile errors →
rm -rf node_modules apps/*/node_modules packages/*/node_modules pnpm-lock.yaml && pnpm install
Step 11 - Commit
This conversion moves the whole tree: naming every moved file would be absurd, so it is the one documented case where a sweeping stage is legitimate, for the files git already tracks, and for them only. git add -u stages moves and rewrites, never a new file: an .env or a .vercel/ folder cannot enter the commit. What the conversion created is then staged by name. First make sure nothing foreign is pending:
git status --short # must show ONLY what this conversion moved, created or rewrote; stop and ask if anything else is pending
HYPERVIBE_GUARD_ALLOW_SWEEP=1 git add -u
git add -- package.json pnpm-workspace.yaml turbo.json apps/web/.gitignore
test -d packages/db && git add -- packages/db
git status --short # what is staged: no .env, no .vercel/, nothing this conversion did not touch
git commit -m "refactor: convert to Turborepo monorepo"⚠️ Don't push automatically - let the caller (/add-automation) decide when to push.
Step 12 - Point the site's hosting at apps/web/, then return to caller
The site now lives in apps/web/, and its hosting still builds the repository's root: from the next push on, every deployment of the site would fail (the live site keeps its last version, and nothing new goes online). Before anything is pushed, the person changes one setting. Tell the user:
✅ Conversion to a Turborepo monorepo complete. Your app now lives in
apps/web/<if has-db>, and your shared DB inpackages/db/</if>.One setting to change on Vercel before the next push, or every deployment of your site will fail from then on (your live site stays as it is, but nothing new goes online):
- Open your project on https://vercel.com, then Settings → Build and Deployment
- Root Directory:
apps/web, then SaveTell me once it is done.
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.
Wait for the confirmation, and pass it on to the caller: it pushes only once the setting is changed, then checks that the site still deploys.
Return control to the calling skill (/add-automation).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

