원클릭으로
mern-scaffold
Scaffold a pnpm + Turborepo MERN monorepo with Next.js, tooling, tests, CI, and optional GitHub repo creation.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Scaffold a pnpm + Turborepo MERN monorepo with Next.js, tooling, tests, CI, and optional GitHub repo creation.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Configure GitHub repository security with branch protection, Dependabot, security scanning, and CI workflows. Integrates with mern-scaffold, nean-scaffold, and iOS projects.
Harden a Vercel deployment with security headers, CSP, bot protection, and deployment configuration
Add authentication to an iOS app with Sign in with Apple, biometrics, and Keychain storage.
Scaffold a new feature with View, ViewModel, and tests following ios-std conventions.
Review iOS code for compliance with standards, NFRs, and security policy.
Manage Swift Package Manager dependencies with security checks and update verification.
| name | mern-scaffold |
| description | Scaffold a pnpm + Turborepo MERN monorepo with Next.js, tooling, tests, CI, and optional GitHub repo creation. |
| argument-hint | [app-name] [--github] [--public] [--org <org>] [--repo <n>] [--no-push] |
| allowed-tools | Bash, Write, Read, Glob, Grep |
Create a fully working MERN repo (Next.js + TypeScript + pnpm workspaces + Turborepo) with tooling configured and runnable immediately.
app-name — Project folder name (default: "app"). Use . to scaffold in the current directory (must be empty or near-empty).--github — Create GitHub repo and push (requires gh auth)--public — Make GitHub repo public (default: private)--org <n> — Create under org instead of personal account--repo <n> — Override repo name (default: app-name)--no-push — Create repo and commit but don't pushCopy files from templates/ into the project. If a template doesn't exist, generate equivalent content.
Templates provide:
<app-name>/
├── apps/web/ # Next.js app (app router + Tailwind)
│ ├── e2e/ # Playwright e2e tests
│ │ └── health.spec.ts # Health check e2e test
│ └── src/
│ ├── app/api/health/ # Health check endpoint (app router)
│ │ └── route.ts
│ ├── __tests__/ # Test setup + smoke tests
│ │ ├── setup.tsx
│ │ └── smoke.test.ts
│ └── server/ # Server utilities from templates
├── packages/shared/ # Zod schemas + types
│ ├── package.json
│ └── src/
├── docs/ # Documentation
│ └── PRD-TEMPLATE.md # Product requirements template for Ralph
├── .vscode/ # VS Code workspace config (from templates)
│ ├── settings.json
│ └── extensions.json
├── .github/ # GitHub config (from templates)
│ ├── workflows/
│ │ ├── ci.yml # CI pipeline (lint, format, typecheck, test, build, e2e)
│ │ ├── security.yml # Dependency review + TruffleHog
│ │ └── pr-check.yml # PR size labeler, commitlint, WIP check
│ ├── dependabot.yml # Automated dependency updates
│ ├── CODEOWNERS # Required reviewers by path
│ ├── SECURITY.md # Security policy
│ └── pull_request_template.md # PR template with checklist
├── .env.local # Local env (gitignored)
├── .env.example # Env template (committed)
├── CLAUDE.md # Repo context for Claude Code
└── (root configs) # eslint, prettier, turbo, pnpm-workspace
{
"name": "<app-name>",
"private": true,
"packageManager": "pnpm@10.5.2",
"scripts": {
"dev": "turbo run dev",
"build": "turbo run build",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --check .",
"format:write": "prettier --write .",
"test": "turbo run test",
"test:e2e": "turbo run test:e2e",
"typecheck": "turbo run typecheck"
},
"pnpm": {
"onlyBuiltDependencies": ["husky"]
}
}
pnpm-workspace.yamlturbo.jsoneslint.config.mjs (uses eslint-plugin-import-x for flat config)prettier.config.cjs.prettierignoreREADME.mdCLAUDE.md.vscode/settings.json.vscode/extensions.jsonmkdir -p apps
pnpm dlx create-next-app@latest "$(pwd)/apps/web" --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-pnpm --yes --disable-git
Important: Use absolute path for the target directory. CNA will not create parent directories and fails with "not writable" if apps/ doesn't exist.
Flags explained:
--yes skips all interactive prompts (React Compiler, etc.)--disable-git prevents CNA from running git init (we handle git ourselves)Remove CNA artifacts (root config handles linting; monorepo has its own lockfile):
rm -f apps/web/eslint.config.mjs apps/web/pnpm-lock.yaml apps/web/pnpm-workspace.yaml
Update apps/web/package.json scripts:
"lint": "next lint" with "lint": "eslint ."
(Next.js 16 removed next lint; root eslint handles it anyway){
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint .",
"test": "vitest run",
"test:watch": "vitest",
"test:e2e": "playwright test",
"typecheck": "tsc --noEmit"
}
}
pnpm add -D eslint @eslint/js@^9 globals typescript-eslint @next/eslint-plugin-next eslint-plugin-react-hooks eslint-plugin-react-refresh eslint-plugin-import-x eslint-plugin-unused-imports vitest @vitest/coverage-v8 turbo prettier -w
apps/web/vitest.config.tsapps/web/src/__tests__/setup.tsxapps/web/playwright.config.tspnpm --filter web add -D @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom @playwright/test vitest @vitest/coverage-v8
pnpm --filter web exec playwright install chromium
Note: Playwright is installed in the web workspace, not root. Use --filter web to run from the correct scope.
env.tshttp/response.tshttp/rateLimit.tshttp/validate.tshttp/securityHeaders.tsdb/sanitize.tsdb/mongoose.tspnpm --filter web add zod mongoose
Create packages/shared/package.json:
{
"name": "@repo/shared",
"version": "0.0.0",
"private": true,
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"lint": "eslint .",
"test": "vitest run --passWithNoTests",
"typecheck": "tsc --noEmit"
}
}
Create packages/shared/tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"declaration": true,
"declarationMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
Copy shared source files from templates:
packages/shared/src/index.tspackages/shared/src/schemas/example.tsInstall shared dependencies:
pnpm --filter @repo/shared add zod
pnpm --filter @repo/shared add -D typescript vitest
Add workspace reference in web app:
pnpm --filter web add '@repo/shared@workspace:*'
Note: Single quotes required — zsh expands unquoted * as a glob.
Copy docs/PRD-TEMPLATE.md from templates.
Create apps/web/src/app/api/health/route.ts:
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({ ok: true, data: { status: "ok" } });
}
Create apps/web/src/__tests__/smoke.test.ts:
import { describe, it, expect } from "vitest";
describe("smoke test", () => {
it("should pass a basic assertion", () => {
expect(1 + 1).toBe(2);
});
});
Create apps/web/e2e/health.spec.ts:
import { test, expect } from "@playwright/test";
test("health endpoint returns ok", async ({ request }) => {
const response = await request.get("/api/health");
expect(response.ok()).toBeTruthy();
const body = await response.json();
expect(body).toEqual({ ok: true, data: { status: "ok" } });
});
.env.local (gitignored):
MONGODB_URI=mongodb://localhost:27017/hello-mern
.env.example (committed):
MONGODB_URI=mongodb://localhost:27017/myapp
node_modules
.next
dist
build
out
coverage
.turbo
.env.local
.env.test
*.tsbuildinfo
playwright-report
test-results
Copy all .github/ files from templates. Replace __GITHUB_USER__ in
dependabot.yml and CODEOWNERS with the GitHub username (from gh api user
or the --org argument). Replace __APP_NAME__ in ci.yml with the project name.
pnpm install
pnpm lint
pnpm format
pnpm typecheck
pnpm test
pnpm build
pnpm test:e2e
Fix any failures and re-run until all pass.
git init
This prepares the repo for the github-hooks step.
gh auth status to succeedgh repo create <owner>/<repo> --<visibility> --source . --remote origin--no-pushAfter scaffolding, run these skills to complete GitHub security setup:
/github-hooks --platform mern — Install local Git hooks
/github-secure (if --github was used) — Configure repo security via GitHub API
These are invoked automatically by /mern-kit.
Summarize: structure created, commands available, what tooling is included, GitHub status if applicable, and remind to run github-hooks/github-secure if not using mern-kit.