Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Creates plan.md, task.md, persona.md, project-context.md, and CLAUDE.md for new self-learning resource projects. Use when: (1) /init command is invoked, (2) setting up a new tutorial/guide/documentation project, (3) structure-designer agent needs templates for learning resource structure design. Provides hierarchical Part/Chapter/Section templates with page allocation.
.claude/skills/aiskillstore-project-scaffolder/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 135% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 203% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 204% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 226% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 200% | 0% |
Quick project setup with templates, best practices, and complete configuration for various frameworks and languages.
You are a project scaffolding expert. When invoked:
@project-scaffolder Create React + TypeScript app
@project-scaffolder --template express-api
@project-scaffolder --monorepo turborepo
@project-scaffolder --cli go
@project-scaffolder --library npm-packagebash# Initialize project npm create vite@latest my-app -- --template react-ts cd my-app npm install # Add essential dependencies npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin npm install -D prettier eslint-config-prettier eslint-plugin-prettier npm install -D husky lint-staged npm install -D vitest @testing-library/react @testing-library/jest-dom npm install -D @vitejs/plugin-react
Directory Structure:
my-app/
├── src/
│ ├── components/
│ │ ├── common/
│ │ └── features/
│ ├── hooks/
│ ├── utils/
│ ├── services/
│ ├── types/
│ ├── styles/
│ ├── App.tsx
│ └── main.tsx
├── public/
├── tests/
│ ├── unit/
│ └── integration/
├── .github/
│ └── workflows/
│ └── ci.yml
├── .husky/
│ └── pre-commit
├── .eslintrc.json
├── .prettierrc
├── .gitignore
├── tsconfig.json
├── vite.config.ts
├── package.json
└── README.md.eslintrc.json:
json{ "parser": "@typescript-eslint/parser", "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "plugin:react-hooks/recommended", "prettier" ], "plugins": ["@typescript-eslint", "react", "react-hooks", "prettier"], "rules": { "prettier/prettier": "error", "react/react-in-jsx-scope": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] }, "settings": { "react": { "version": "detect" } } }
.prettierrc:
json{ "semi": true, "trailingComma": "es5", "singleQuote": true, "printWidth": 100, "tabWidth": 2, "useTabs": false }
vite.config.ts:
typescriptimport { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import path from 'path'; export default defineConfig({ plugins: [react()], resolve: { alias: { '@': path.resolve(__dirname, './src'), '@components': path.resolve(__dirname, './src/components'), '@hooks': path.resolve(__dirname, './src/hooks'), '@utils': path.resolve(__dirname, './src/utils'), '@types': path.resolve(__dirname, './src/types'), }, }, test: { globals: true, environment: 'jsdom', setupFiles: './tests/setup.ts', }, });
package.json scripts:
json{ "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", "lint": "eslint src --ext .ts,.tsx", "lint:fix": "eslint src --ext .ts,.tsx --fix", "format": "prettier --write \"src/**/*.{ts,tsx,css}\"", "test": "vitest", "test:ui": "vitest --ui", "test:coverage": "vitest --coverage", "prepare": "husky install" } }
bash# Initialize project mkdir my-api && cd my-api npm init -y npm install express cors helmet dotenv npm install -D typescript @types/node @types/express @types/cors npm install -D ts-node-dev npm install -D eslint prettier npm install -D jest @types/jest ts-jest supertest @types/supertest
Directory Structure:
my-api/
├── src/
│ ├── config/
│ │ └── database.ts
│ ├── controllers/
│ ├── middleware/
│ │ ├── errorHandler.ts
│ │ ├── validation.ts
│ │ └── auth.ts
│ ├── models/
│ ├── routes/
│ │ └── index.ts
│ ├── services/
│ ├── utils/
│ │ ├── logger.ts
│ │ └── asyncHandler.ts
│ ├── types/
│ │ └── express.d.ts
│ ├── app.ts
│ └── server.ts
├── tests/
│ ├── unit/
│ └── integration/
├── .env.example
├── .gitignore
├── tsconfig.json
├── jest.config.js
├── package.json
└── README.mdsrc/app.ts:
typescriptimport express, { Application } from 'express'; import cors from 'cors'; import helmet from 'helmet'; import { errorHandler } from './middleware/errorHandler'; import routes from './routes'; const app: Application = express(); // Security middleware app.use(helmet()); app.use(cors()); // Body parsing middleware app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Routes app.use('/api', routes); // Health check app.get('/health', (req, res) => { res.status(200).json({ status: 'ok', timestamp: new Date().toISOString() }); }); // Error handling app.use(errorHandler); export default app;
src/server.ts:
typescriptimport app from './app'; import dotenv from 'dotenv'; dotenv.config(); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
src/middleware/errorHandler.ts:
typescriptimport { Request, Response, NextFunction } from 'express'; export class AppError extends Error { statusCode: number; isOperational: boolean; constructor(message: string, statusCode: number) { super(message); this.statusCode = statusCode; this.isOperational = true; Error.captureStackTrace(this, this.constructor); } } export const errorHandler = ( err: Error, req: Request, res: Response, next: NextFunction ) => { if (err instanceof AppError) { return res.status(err.statusCode).json({ status: 'error', message: err.message, }); } console.error('ERROR:', err); return res.status(500).json({ status: 'error', message: 'Internal server error', }); };
src/utils/asyncHandler.ts:
typescriptimport { Request, Response, NextFunction } from 'express'; export const asyncHandler = ( fn: (req: Request, res: Response, next: NextFunction) => Promise<any> ) => { return (req: Request, res: Response, next: NextFunction) => { Promise.resolve(fn(req, res, next)).catch(next); }; };
tsconfig.json:
json{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "moduleResolution": "node", "baseUrl": ".", "paths": { "@/*": ["src/*"], "@controllers/*": ["src/controllers/*"], "@services/*": ["src/services/*"], "@models/*": ["src/models/*"], "@middleware/*": ["src/middleware/*"], "@utils/*": ["src/utils/*"] } }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "tests"] }
package.json scripts:
json{ "scripts": { "dev": "ts-node-dev --respawn --transpile-only src/server.ts", "build": "tsc", "start": "node dist/server.js", "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", "lint": "eslint src --ext .ts", "lint:fix": "eslint src --ext .ts --fix" } }
bash# Create project directory mkdir my-fastapi-app && cd my-fastapi-app # Create virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install dependencies pip install fastapi uvicorn pydantic python-dotenv pip install pytest pytest-cov pytest-asyncio httpx pip install black flake8 mypy isort
Directory Structure:
my-fastapi-app/
├── app/
│ ├── api/
│ │ ├── __init__.py
│ │ ├── dependencies.py
│ │ └── routes/
│ │ ├── __init__.py
│ │ └── users.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── config.py
│ │ └── security.py
│ ├── models/
│ │ ├── __init__.py
│ │ └── user.py
│ ├── schemas/
│ │ ├── __init__.py
│ │ └── user.py
│ ├── services/
│ │ ├── __init__.py
│ │ └── user_service.py
│ ├── db/
│ │ ├── __init__.py
│ │ └── session.py
│ ├── __init__.py
│ └── main.py
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ └── test_api/
│ └── test_users.py
├── .env.example
├── .gitignore
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
├── pytest.ini
└── README.mdapp/main.py:
pythonfrom fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.api.routes import users from app.core.config import settings app = FastAPI( title=settings.PROJECT_NAME, version=settings.VERSION, description=settings.DESCRIPTION, ) # CORS app.add_middleware( CORSMiddleware, allow_origins=settings.ALLOWED_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include routers app.include_router(users.router, prefix="/api/users", tags=["users"]) @app.get("/health") async def health_check(): return {"status": "ok"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
app/core/config.py:
pythonfrom pydantic_settings import BaseSettings from typing import List class Settings(BaseSettings): PROJECT_NAME: str = "My FastAPI App" VERSION: str = "1.0.0" DESCRIPTION: str = "FastAPI application" # CORS ALLOWED_ORIGINS: List[str] = ["http://localhost:3000"] # Database DATABASE_URL: str = "sqlite:///./app.db" # Security SECRET_KEY: str = "your-secret-key-here" ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 class Config: env_file = ".env" case_sensitive = True settings = Settings()
app/schemas/user.py:
pythonfrom pydantic import BaseModel, EmailStr from datetime import datetime from typing import Optional class UserBase(BaseModel): email: EmailStr username: str class UserCreate(UserBase): password: str class UserUpdate(BaseModel): email: Optional[EmailStr] = None username: Optional[str] = None class UserResponse(UserBase): id: int created_at: datetime class Config: from_attributes = True
pyproject.toml:
toml[tool.black] line-length = 100 target-version = ['py311'] include = '\.pyi?$' [tool.isort] profile = "black" line_length = 100 [tool.mypy] python_version = "3.11" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"]
requirements.txt:
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.0
pydantic-settings==2.1.0
python-dotenv==1.0.0requirements-dev.txt:
-r requirements.txt
pytest==7.4.3
pytest-cov==4.1.0
pytest-asyncio==0.21.1
httpx==0.25.2
black==23.11.0
flake8==6.1.0
mypy==1.7.1
isort==5.12.0bash# Initialize Go module mkdir my-cli && cd my-cli go mod init github.com/username/my-cli # Install dependencies go get github.com/spf13/cobra@latest go get github.com/spf13/viper@latest
Directory Structure:
my-cli/
├── cmd/
│ ├── root.go
│ └── version.go
├── internal/
│ ├── config/
│ │ └── config.go
│ ├── cli/
│ │ └── ui.go
│ └── utils/
│ └── helpers.go
├── pkg/
│ └── api/
│ └── client.go
├── tests/
├── .gitignore
├── go.mod
├── go.sum
├── main.go
├── Makefile
└── README.mdmain.go:
gopackage main import ( "github.com/username/my-cli/cmd" ) func main() { cmd.Execute() }
cmd/root.go:
gopackage cmd import ( "fmt" "os" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( cfgFile string verbose bool ) var rootCmd = &cobra.Command{ Use: "my-cli", Short: "A brief description of your CLI", Long: `A longer description of your CLI application`, } func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.my-cli.yaml)") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output") } func initConfig() { if cfgFile != "" { viper.SetConfigFile(cfgFile) } else { home, err := os.UserHomeDir() cobra.CheckErr(err) viper.AddConfigPath(home) viper.SetConfigType("yaml") viper.SetConfigName(".my-cli") } viper.AutomaticEnv() if err := viper.ReadInConfig(); err == nil { fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) } }
Makefile:
makefile.PHONY: build test clean install BINARY_NAME=my-cli VERSION=$(shell git describe --tags --always --dirty) LDFLAGS=-ldflags "-X main.Version=${VERSION}" build: go build ${LDFLAGS} -o bin/${BINARY_NAME} main.go test: go test -v ./... test-coverage: go test -v -coverprofile=coverage.out ./... go tool cover -html=coverage.out clean: go clean rm -rf bin/ install: go install ${LDFLAGS} lint: golangci-lint run run: go run main.go
bash# Create monorepo npx create-turbo@latest my-monorepo cd my-monorepo
Directory Structure:
my-monorepo/
├── apps/
│ ├── web/ # Next.js app
│ ├── api/ # Express API
│ └── docs/ # Documentation site
├── packages/
│ ├── ui/ # Shared UI components
│ ├── config/ # Shared configs (eslint, tsconfig)
│ ├── types/ # Shared TypeScript types
│ └── utils/ # Shared utilities
├── turbo.json
├── package.json
└── README.mdturbo.json:
json{ "$schema": "https://turbo.build/schema.json", "pipeline": { "build": { "dependsOn": ["^build"], "outputs": [".next/**", "dist/**"] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }, "lint": { "outputs": [] }, "dev": { "cache": false, "persistent": true } } }
Root package.json:
json{ "name": "my-monorepo", "private": true, "workspaces": ["apps/*", "packages/*"], "scripts": { "dev": "turbo run dev", "build": "turbo run build", "test": "turbo run test", "lint": "turbo run lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"" }, "devDependencies": { "turbo": "latest", "prettier": "latest" } }
# Dependencies
node_modules/
.pnp
.pnp.js
# Testing
coverage/
*.lcov
# Production
build/
dist/
# Environment
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Logs
logs/
*.log
npm-debug.log*bash# Application NODE_ENV=development PORT=3000 APP_URL=http://localhost:3000 # Database DATABASE_URL=postgresql://user:password@localhost:5432/mydb # Authentication JWT_SECRET=your-secret-key-here JWT_EXPIRE=7d # API Keys API_KEY=your-api-key
yamlname: CI on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: test: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run linter run: npm run lint - name: Run tests run: npm test - name: Build run: npm run build
markdown## Project Setup Checklist ### Initial Setup - [ ] Project directory created - [ ] Package manager initialized (npm, pip, go mod) - [ ] Git repository initialized - [ ] .gitignore configured - [ ] README.md created ### Configuration - [ ] Linting configured (ESLint, Pylint, etc.) - [ ] Formatting configured (Prettier, Black, etc.) - [ ] TypeScript configured (if applicable) - [ ] Testing framework set up - [ ] Environment variables documented ### Development Tools - [ ] Pre-commit hooks installed - [ ] VS Code settings configured - [ ] Debugging configuration added - [ ] Scripts for common tasks added ### CI/CD - [ ] GitHub Actions workflow created - [ ] Build pipeline configured - [ ] Test automation set up - [ ] Deployment process documented ### Documentation - [ ] Setup instructions written - [ ] API documentation started - [ ] Contributing guidelines added - [ ] License file added
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 23,443 | 25,251 | +8% | 1 | 1 | 0% | 4,592 | 10,341 | +125% | 0 | 0 | — |
case-02 | fail→pass | 22,094 | 22,268 | +1% | 1 | 1 | 0% | 4,532 | 10,653 | +135% | 0 | 0 | — |
case-03 | fail→fail | 23,359 | 26,508 | +13% | 1 | 1 | 0% | 4,872 | 10,628 | +118% | 0 | 0 | — |
case-04 | fail→fail | 23,544 | 28,943 | +23% | 1 | 1 | 0% | 3,543 | 9,147 | +158% | 0 | 0 | — |
case-05 | fail→fail | 19,629 | 27,057 | +38% | 1 | 1 | 0% | 3,836 | 9,715 | +153% | 0 | 0 | — |
case-06 | pass→pass | 19,891 | 22,379 | +13% | 1 | 1 | 0% | 2,812 | 9,176 | +226% | 0 | 0 | — |
case-07 | pass→pass | 15,595 | 22,282 | +43% | 1 | 1 | 0% | 3,158 | 9,475 | +200% | 0 | 0 | — |
case-08 | fail→pass | 16,140 | 18,215 | +13% | 1 | 1 | 0% | 3,103 | 9,409 | +203% | 0 | 0 | — |
case-09 | pass→pass | 42,362 | 25,041 | -41% | 1 | 1 | 0% | 2,999 | 9,776 | +226% | 0 | 0 | — |
case-10 | fail→fail | 15,625 | 17,301 | +11% | 1 | 1 | 0% | 2,808 | 9,449 | +237% | 0 | 0 | — |
case-11 | pass→pass | 16,203 | 22,644 | +40% | 1 | 1 | 0% | 2,150 | 8,406 | +291% | 0 | 0 | — |
case-12 | fail→fail | 12,941 | 17,522 | +35% | 1 | 1 | 0% | 2,466 | 8,836 | +258% | 0 | 0 | — |
case-13 | pass→pass | 20,926 | 16,355 | -22% | 1 | 1 | 0% | 3,056 | 9,254 | +203% | 0 | 0 | — |
case-14 | fail→fail | 11,792 | 9,799 | -17% | 1 | 1 | 0% | 2,198 | 7,886 | +259% | 0 | 0 | — |
case-15 | fail→fail | 24,570 | 18,670 | -24% | 1 | 1 | 0% | 3,353 | 9,253 | +176% | 0 | 0 | — |
case-16 | fail→pass | 15,173 | 22,124 | +46% | 1 | 1 | 0% | 2,757 | 8,369 | +204% | 0 | 0 | — |
case-17 | fail→fail | 19,247 | 18,259 | -5% | 1 | 1 | 0% | 2,715 | 8,559 | +215% | 0 | 0 | — |
case-18 | pass→pass | 14,535 | 25,705 | +77% | 1 | 1 | 0% | 2,615 | 8,846 | +238% | 0 | 0 | — |
case-19 | fail→fail | 17,002 | 18,094 | +6% | 1 | 1 | 0% | 2,984 | 9,220 | +209% | 0 | 0 | — |
case-20 | pass→pass | 10,985 | 6,090 | -45% | 1 | 1 | 0% | 1,116 | 7,117 | +538% | 0 | 0 | — |
case-21 | pass→pass | 11,908 | 7,588 | -36% | 1 | 1 | 0% | 1,313 | 7,419 | +465% | 0 | 0 | — |
case-22 | pass→pass | 16,642 | 19,247 | +16% | 1 | 1 | 0% | 2,336 | 8,763 | +275% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.