12 KiB
opencode Monorepo Config Adoption Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Adopt opencode-style monorepo config: Turbo task orchestration, workspace dep
catalog, shared root tsconfig, bunfig.toml, and exports field in all packages.
Architecture: Pure config changes across 10 files — no source code touched. Root config files are added/updated first, then per-package files updated to reference them. Changes are independent within each task and safe to commit atomically.
Tech Stack: Bun workspaces, Turbo 2.x, @tsconfig/bun, TypeScript (tsgo / @typescript/native-preview)
File Map
| File | Action | Responsible for |
|---|---|---|
package.json |
Modify | Workspace catalog, turbo devDep, @tsconfig/bun devDep, updated scripts |
turbo.json |
Create | Task graph: typecheck, build, test |
tsconfig.json |
Create | Shared TS compiler options for all packages |
bunfig.toml |
Create | Exact installs, root test guard |
packages/core/package.json |
Modify | exports field, catalog refs, script rename |
packages/api-server/package.json |
Modify | exports field, catalog refs, script rename |
packages/mcp-server/package.json |
Modify | exports field, catalog refs, script rename |
packages/core/tsconfig.json |
Modify | Slim — extends root, paths only |
packages/api-server/tsconfig.json |
Modify | Slim — extends root, paths only |
packages/mcp-server/tsconfig.json |
Modify | Slim — extends root, paths only |
Task 1: Add bunfig.toml and turbo.json
Two new root config files with no dependencies on other tasks.
Files:
-
Create:
bunfig.toml -
Create:
turbo.json -
Step 1: Create
bunfig.toml
Write this file at repo root (/path/to/ca-marketplace-scraper/bunfig.toml):
[install]
exact = true
[test]
root = "./do-not-run-tests-from-root"
- Step 2: Create
turbo.json
Write this file at repo root:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"typecheck": {},
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["^build"],
"outputs": []
}
}
}
- Step 3: Verify files exist
Run:
ls bunfig.toml turbo.json
Expected: both files listed, no errors.
- Step 4: Commit
git add bunfig.toml turbo.json
git commit -m "chore: add bunfig.toml and turbo.json"
Task 2: Create root tsconfig.json
Shared base tsconfig all packages will extend. Extracts the common options currently duplicated in all 3 per-package tsconfigs.
Files:
-
Create:
tsconfig.json -
Step 1: Create root
tsconfig.json
Write this file at repo root:
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/bun/tsconfig.json",
"compilerOptions": {
"lib": ["dom", "ESNext"],
"target": "ESNext",
"module": "preserve",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}
- Step 2: Commit
git add tsconfig.json
git commit -m "chore: add shared root tsconfig.json"
Task 3: Update root package.json
Add workspace catalog, turbo + @tsconfig/bun devDependencies, and update scripts to
use turbo run.
Files:
-
Modify:
package.json -
Step 1: Replace root
package.json
Write this complete file:
{
"name": "marketplace-scrapers-monorepo",
"version": "1.0.0",
"private": true,
"type": "module",
"packageManager": "bun@1.3.13",
"scripts": {
"typecheck": "turbo run typecheck",
"build": "bun run clean && turbo run build",
"build:api": "bun build ./packages/api-server/src/index.ts --target=bun --outdir=./dist/api --minify",
"build:mcp": "bun build ./packages/mcp-server/src/index.ts --target=bun --outdir=./dist/mcp --minify",
"build:all": "bun run build:api && bun run build:mcp",
"ci": "biome ci",
"clean": "rm -rf dist",
"start": "./scripts/start.sh"
},
"workspaces": {
"packages": [
"packages/*"
],
"catalog": {
"@tsconfig/bun": "1.0.9",
"@typescript/native-preview": "7.0.0-dev.20260428.1",
"@types/bun": "1.2.18",
"@types/cli-progress": "3.11.6",
"@types/unidecode": "1.1.0"
}
},
"devDependencies": {
"@biomejs/biome": "2.3.11",
"@tsconfig/bun": "catalog:",
"turbo": "2.5.4"
}
}
Note on catalog versions: The catalog pins exact versions. The values above are taken from the current package installs. If
@types/bunwaslatest, checknode_modules/@types/bun/package.jsonfor the actual installed version and use that. Same for@typescript/native-preview.
- Step 2: Check actual installed versions
Run:
cat node_modules/@types/bun/package.json | grep '"version"'
cat node_modules/@typescript/native-preview/package.json | grep '"version"'
cat node_modules/@types/cli-progress/package.json | grep '"version"'
cat node_modules/@types/unidecode/package.json | grep '"version"'
Update the catalog values in package.json to match the exact installed versions.
- Step 3: Install turbo and @tsconfig/bun
bun install
Expected: lock file updated, turbo and @tsconfig/bun appear in node_modules.
- Step 4: Verify turbo works
bunx turbo run typecheck --dry
Expected: output lists the typecheck task for each package (even if no typecheck
script exists yet — turbo will note them as skipped/missing).
- Step 5: Commit
git add package.json bun.lock
git commit -m "chore: add workspace catalog and turbo to root package.json"
Task 4: Update per-package package.json files
Rename type:check → typecheck, replace main/module with exports, swap pinned
dep versions for catalog: references.
Files:
-
Modify:
packages/core/package.json -
Modify:
packages/api-server/package.json -
Modify:
packages/mcp-server/package.json -
Step 1: Replace
packages/core/package.json
{
"name": "@marketplace-scrapers/core",
"version": "1.0.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"private": true,
"scripts": {
"typecheck": "bun tsgo"
},
"dependencies": {
"@typescript/native-preview": "catalog:",
"cli-progress": "^3.12.0",
"linkedom": "^0.18.12",
"unidecode": "^1.1.0"
},
"devDependencies": {
"@types/bun": "catalog:",
"@types/cli-progress": "catalog:",
"@types/unidecode": "catalog:"
},
"peerDependencies": {
"typescript": "^5"
}
}
- Step 2: Replace
packages/api-server/package.json
{
"name": "@marketplace-scrapers/api-server",
"version": "1.0.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"private": true,
"scripts": {
"start": "bun ./src/index.ts",
"dev": "bun --watch ./src/index.ts",
"build": "bun build ./src/index.ts --target=bun --outdir=../../dist/api",
"typecheck": "bun tsgo"
},
"dependencies": {
"@marketplace-scrapers/core": "workspace:*",
"@typescript/native-preview": "catalog:"
},
"devDependencies": {
"@types/bun": "catalog:"
},
"peerDependencies": {
"typescript": "^5"
}
}
- Step 3: Replace
packages/mcp-server/package.json
{
"name": "@marketplace-scrapers/mcp-server",
"version": "1.0.0",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"private": true,
"scripts": {
"start": "bun ./src/index.ts",
"dev": "bun --watch ./src/index.ts",
"build": "bun build ./src/index.ts --target=bun --outdir=../../dist/mcp",
"typecheck": "bun tsgo"
},
"dependencies": {
"@marketplace-scrapers/core": "workspace:*",
"@typescript/native-preview": "catalog:"
},
"devDependencies": {
"@types/bun": "catalog:"
},
"peerDependencies": {
"typescript": "^5"
}
}
- Step 4: Run
bun installto sync lockfile
bun install
Expected: no errors.
Catalog refs resolved.
bun.lock updated.
- Step 5: Verify typecheck still works per-package
cd packages/core && bun run typecheck
cd ../api-server && bun run typecheck
cd ../mcp-server && bun run typecheck
cd ../..
Expected: each exits 0 (or same errors as before — no new errors introduced).
- Step 6: Commit
git add packages/core/package.json packages/api-server/package.json packages/mcp-server/package.json bun.lock
git commit -m "chore: use exports field and catalog refs in all packages"
Task 5: Slim per-package tsconfig.json files
Replace the duplicated full tsconfig in each package with a slim extends-based one
pointing to root.
Files:
-
Modify:
packages/core/tsconfig.json -
Modify:
packages/api-server/tsconfig.json -
Modify:
packages/mcp-server/tsconfig.json -
Step 1: Replace
packages/core/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["./src", "./test"]
}
- Step 2: Replace
packages/api-server/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["./src", "./test"]
}
- Step 3: Replace
packages/mcp-server/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["./src", "./test"]
}
- Step 4: Verify
@tsconfig/bunis resolvable
The root tsconfig extends @tsconfig/bun/tsconfig.json. Confirm the package is
installed:
ls node_modules/@tsconfig/bun/tsconfig.json
Expected: file exists.
- Step 5: Run typecheck via Turbo
bun run typecheck
Expected: Turbo runs typecheck for all 3 packages in parallel, all pass (or same
pre-existing errors — no new ones).
- Step 6: Commit
git add packages/core/tsconfig.json packages/api-server/tsconfig.json packages/mcp-server/tsconfig.json
git commit -m "chore: slim per-package tsconfigs to extend root"
Task 6: Smoke test full build pipeline
Verify everything works end-to-end.
Files: none (verification only)
- Step 1: Run turbo typecheck
bun run typecheck
Expected: Turbo runs typecheck across all packages.
Exit 0.
- Step 2: Run full build
bun run build
Expected: dist/ cleaned, Turbo runs build (core first, then api-server and
mcp-server in parallel), build artifacts appear in dist/api/ and dist/mcp/.
- Step 3: Verify dist artifacts
ls dist/api/ dist/mcp/
Expected: compiled output files in both directories.
- Step 4: Verify
bun installis exact
grep -c '\^' bun.lock | head -5
With exact = true in bunfig.toml, new installs won’t add ^ ranges.
Existing ^ ranges in bun.lock from before are fine — they’ll be resolved to exact on
next fresh install.
- Step 5: Final commit if any loose files
git status
If clean: done. If any files modified by bun install (e.g. bun.lock):
git add bun.lock
git commit -m "chore: sync lockfile after monorepo config adoption"