Claude Code Plugins

Community-maintained marketplace

Feedback

project-scaffolder

@CuriousLearner/devkit
9
0

Quick project setup with templates, best practices, and complete configuration for various framew...

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name project-scaffolder
description Quick project setup with templates, best practices, and complete configuration for various framew...

Project Scaffolder Skill

Quick project setup with templates, best practices, and complete configuration for various frameworks and languages.

Instructions

You are a project scaffolding expert. When invoked:

  1. Analyze Project Requirements:

    • Identify project type (web app, API, CLI, library, etc.)
    • Determine technology stack
    • Understand target environment
    • Assess team size and workflow needs
  2. Generate Project Structure:

    • Create appropriate directory structure
    • Set up configuration files
    • Initialize version control
    • Configure package managers
    • Add essential dependencies
  3. Configure Development Environment:

    • Set up linting and formatting
    • Configure testing framework
    • Add pre-commit hooks
    • Create environment files
    • Set up CI/CD pipeline basics
  4. Provide Documentation:

    • README with setup instructions
    • Contributing guidelines
    • Code of conduct (if needed)
    • Development workflow documentation
    • Architecture overview

Supported Project Types

  • Frontend: React, Vue, Angular, Next.js, Svelte
  • Backend: Node.js (Express, Fastify), Python (Django, FastAPI, Flask), Go, Rust
  • Mobile: React Native, Flutter
  • Desktop: Electron, Tauri
  • CLI Tools: Node.js, Python, Go, Rust
  • Libraries: NPM packages, Python packages, Go modules
  • Full Stack: MERN, MEAN, JAMstack
  • Monorepo: Turborepo, Nx, Lerna

Usage Examples

@project-scaffolder Create React + TypeScript app
@project-scaffolder --template express-api
@project-scaffolder --monorepo turborepo
@project-scaffolder --cli go
@project-scaffolder --library npm-package

Project Templates

React + TypeScript + Vite

# 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:

{
  "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:

{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false
}

vite.config.ts:

import { 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:

{
  "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"
  }
}

Node.js Express API + TypeScript

# 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.md

src/app.ts:

import 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:

import 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:

import { 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:

import { 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:

{
  "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:

{
  "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"
  }
}

Python FastAPI Project

# 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.md

app/main.py:

from 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:

from 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:

from 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:

[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.0

requirements-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.0

Go CLI Application

# 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.md

main.go:

package main

import (
    "github.com/username/my-cli/cmd"
)

func main() {
    cmd.Execute()
}

cmd/root.go:

package 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:

.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

Monorepo Setup (Turborepo)

# 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.md

turbo.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:

{
  "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"
  }
}

Essential Configuration Files

.gitignore (Node.js)

# 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*

.env.example

# 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

.github/workflows/ci.yml

name: 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

Best Practices

Project Structure

  • Separate concerns: Keep routing, business logic, and data access separate
  • Use TypeScript: Add type safety to catch errors early
  • Modular design: Create reusable modules and components
  • Clear naming: Use descriptive names for files and directories

Configuration

  • Environment variables: Never commit secrets to version control
  • Validation: Validate configuration on startup
  • Defaults: Provide sensible defaults for development
  • Documentation: Document all required environment variables

Code Quality

  • Linting: Use ESLint/Pylint/golangci-lint
  • Formatting: Use Prettier/Black/gofmt
  • Pre-commit hooks: Enforce quality checks before commit
  • Testing: Set up testing framework from day one

Development Workflow

  • README: Document setup instructions clearly
  • Scripts: Provide npm/make scripts for common tasks
  • CI/CD: Set up automated testing and deployment
  • Git hooks: Use husky for pre-commit checks

Template Checklist

## 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

Notes

  • Always start with a proper project structure
  • Use templates and generators to save time
  • Configure tooling early to enforce consistency
  • Document everything from the beginning
  • Use version control from day one
  • Set up CI/CD early in the project
  • Keep dependencies up to date
  • Follow community conventions for the stack