boilerplate

Generate framework-specific boilerplate code

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "boilerplate" with this command: npx skills add manastalukdar/claude-devstudio/manastalukdar-claude-devstudio-boilerplate

Framework Boilerplate Generator

I'll generate framework-specific boilerplate code following best practices and conventions for React, Vue, Next.js, Express, FastAPI, Django, and more.

Arguments: $ARGUMENTS - component/route/model name and type

Supported Frameworks:

  • Frontend: React, Vue, Next.js, Angular, Svelte
  • Backend: Express, Fastify, NestJS, FastAPI, Django
  • Full-stack: Next.js, Remix, SvelteKit

Token Optimization

This skill uses multiple optimization strategies to minimize token usage while maintaining comprehensive boilerplate generation:

1. Framework Detection Caching (400 token savings)

Pattern: Cache framework detection results to avoid repeated file system checks

# Cache file: .boilerplate-framework.cache
# Format: framework_name
# TTL: 24 hours (framework rarely changes)

if [ -f ".boilerplate-framework.cache" ] && [ $(($(date +%s) - $(stat -c %Y .boilerplate-framework.cache))) -lt 86400 ]; then
    FRAMEWORK=$(cat .boilerplate-framework.cache)
    # 20 tokens vs 420 tokens for full detection
else
    FRAMEWORK=$(detect_framework)  # Full detection (420 tokens)
    echo "$FRAMEWORK" > .boilerplate-framework.cache
fi

Savings:

  • Cached: ~20 tokens (read cache file)
  • Uncached: ~420 tokens (package.json/requirements.txt checks, multiple Grep operations)
  • 400 token savings (95%) for subsequent runs

2. Template Library Approach (2,500 token savings)

Pattern: Use comprehensive pre-defined templates instead of LLM-generated code

# Instead of: LLM-generated boilerplate (3,000+ tokens)
# Use: Template library (500 tokens)

# Template files stored in skill
TEMPLATE_DIR="templates/$FRAMEWORK"

generate_component() {
    local component_name="$1"
    local template_file="$TEMPLATE_DIR/component.template.tsx"

    # Simple variable substitution (100 tokens)
    sed "s/\${COMPONENT_NAME}/$component_name/g" "$template_file"
}

Savings:

  • Template-based: ~500 tokens (file read + substitution)
  • LLM-generated: ~3,000 tokens (full code generation with analysis)
  • 2,500 token savings (83%) per component

3. Grep-Based Configuration Detection (300 token savings)

Pattern: Use Grep to detect project configuration instead of reading files

# Instead of: Read package.json/requirements.txt fully (500 tokens)
# Use: Grep for specific patterns (200 tokens)

# Detect React
HAS_REACT=$(grep -q "\"react\":" package.json && echo "true" || echo "false")

# Detect TypeScript
HAS_TS=$(grep -q "\"typescript\":" package.json && echo "true" || echo "false")

# Detect testing framework
HAS_JEST=$(grep -q "\"jest\":" package.json && echo "true" || echo "false")

Savings:

  • Grep approach: ~200 tokens (pattern matching)
  • Full file read: ~500 tokens (read and parse JSON)
  • 300 token savings (60%)

4. Incremental Scaffolding (1,200 token savings)

Pattern: Generate only requested component type, not entire feature

# Instead of: Full feature scaffolding (4,000+ tokens)
# - Component + styles + tests + stories + types
# Generate: Only component (800 tokens)

case $COMPONENT_TYPE in
    component)
        generate_component "$COMPONENT_NAME"  # 800 tokens
        ;;
    route)
        generate_route "$COMPONENT_NAME"  # 900 tokens
        ;;
    full)
        generate_component "$COMPONENT_NAME"
        generate_styles "$COMPONENT_NAME"
        generate_tests "$COMPONENT_NAME"
        generate_types "$COMPONENT_NAME"  # 4,000 tokens
        ;;
esac

Savings:

  • Component only: ~800 tokens
  • Full feature: ~4,000 tokens
  • 1,200 token savings (75%) when generating single component

5. Early Exit for Existing Components (90% savings)

Pattern: Check if component already exists before generating

# Quick check: Does component exist?
case $FRAMEWORK in
    react)
        component_path="src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.tsx"
        ;;
    nextjs)
        component_path="app/${COMPONENT_NAME}/page.tsx"
        ;;
esac

if [ -f "$component_path" ]; then
    echo "⚠️  Component $COMPONENT_NAME already exists at $component_path"
    read -p "Overwrite? (y/n): " confirm
    if [ "$confirm" != "y" ]; then
        echo "✓ Keeping existing component"
        exit 0  # 200 tokens total
    fi
fi

# Otherwise: Full generation (3,500+ tokens)

Savings:

  • Existing component: ~200 tokens (early exit)
  • Full generation: ~3,500+ tokens
  • 3,300+ token savings (94%) when component exists

6. Framework-Specific Template Caching (800 token savings)

Pattern: Cache loaded templates per framework

# Cache file: .boilerplate-templates-${FRAMEWORK}.cache
# Contains pre-loaded templates for the framework
# TTL: 24 hours

load_templates() {
    local cache_file=".boilerplate-templates-${FRAMEWORK}.cache"

    if [ -f "$cache_file" ]; then
        source "$cache_file"  # 150 tokens
        return
    fi

    # Load all templates for framework (950 tokens)
    case $FRAMEWORK in
        react)
            TEMPLATE_COMPONENT=$(cat templates/react/component.tsx)
            TEMPLATE_TEST=$(cat templates/react/test.tsx)
            TEMPLATE_STYLES=$(cat templates/react/styles.css)
            ;;
        nextjs)
            TEMPLATE_PAGE=$(cat templates/nextjs/page.tsx)
            TEMPLATE_API=$(cat templates/nextjs/api-route.ts)
            ;;
    esac

    declare -p TEMPLATE_* > "$cache_file"
}

Savings:

  • Cached templates: ~150 tokens
  • Load templates: ~950 tokens (multiple file reads)
  • 800 token savings (84%) for subsequent runs

7. Component Inventory Tracking (400 token savings)

Pattern: Track generated components to avoid duplicates

# Cache file: .boilerplate-generated.cache
# Format: framework:component_type:component_name:file_path
# TTL: Session-based (cleared manually)

is_component_generated() {
    local component_name="$1"
    local component_type="$2"
    grep -q "^$FRAMEWORK:$component_type:$component_name:" .boilerplate-generated.cache 2>/dev/null
}

# Track generated components
if ! is_component_generated "$COMPONENT_NAME" "$COMPONENT_TYPE"; then
    generate_boilerplate
    echo "$FRAMEWORK:$COMPONENT_TYPE:$COMPONENT_NAME:$component_path" >> .boilerplate-generated.cache
else
    echo "  ✓ $COMPONENT_NAME already generated"
fi

Savings:

  • Skip duplicate: ~50 tokens (cache check)
  • Generate new: ~450 tokens (template processing)
  • 400 token savings (89%) for duplicate prevention

8. Test File Generation Optimization (600 token savings)

Pattern: Generate minimal test boilerplate with placeholders

# Instead of: Comprehensive test suite (1,200 tokens)
# Use: Minimal test template with TODOs (600 tokens)

generate_minimal_test() {
    local component_name="$1"

    cat <<EOF
import { render, screen } from '@testing-library/react';
import { ${component_name} } from './${component_name}';

describe('${component_name}', () => {
  it('renders without crashing', () => {
    render(<${component_name} />);
  });

  // TODO: Add more tests
});
EOF
}

Savings:

  • Minimal test: ~200 tokens (basic structure)
  • Comprehensive test: ~800 tokens (multiple test cases)
  • 600 token savings (75%)
  • Users can expand tests as needed

9. Real-World Token Usage Distribution

Typical Scenarios:

  1. First Run - Single Component (2,000-3,000 tokens)

    • Framework detection: 420 tokens
    • Load templates: 950 tokens
    • Generate component: 800 tokens
    • Generate test: 200 tokens
    • Generate styles: 150 tokens
    • Total: ~2,520 tokens
  2. Subsequent Run - Same Framework (800-1,500 tokens)

    • Framework detection (cached): 20 tokens
    • Load templates (cached): 150 tokens
    • Generate component: 800 tokens
    • Generate test: 200 tokens
    • Total: ~1,170 tokens
  3. Component Exists (150-250 tokens)

    • Framework detection (cached): 20 tokens
    • Check existing: 100 tokens
    • Early exit: 50 tokens
    • Total: ~170 tokens
  4. Full Feature Scaffold (4,000-6,000 tokens)

    • Framework detection: 420 tokens
    • Load templates: 950 tokens
    • Generate component: 800 tokens
    • Generate test: 800 tokens
    • Generate styles: 150 tokens
    • Generate types: 400 tokens
    • Generate story: 300 tokens
    • Total: ~3,820 tokens
  5. API Route Only (600-1,000 tokens)

    • Framework detection (cached): 20 tokens
    • Load API template: 150 tokens
    • Generate route: 600 tokens
    • Total: ~770 tokens

Expected Token Savings:

  • Average 53% reduction from baseline (3,000 → 1,400 tokens)
  • 94% reduction when component already exists
  • Aggregate savings: 1,500-2,000 tokens per boilerplate generation

Optimization Summary

StrategySavingsWhen Applied
Framework detection caching400 tokens (95%)Subsequent runs
Template library approach2,500 tokens (83%)Always
Grep-based config detection300 tokens (60%)Always
Incremental scaffolding1,200 tokens (75%)Component-only generation
Early exit for existing3,300 tokens (94%)Component exists
Template caching800 tokens (84%)Subsequent runs
Component inventory400 tokens (89%)Duplicate prevention
Minimal test generation600 tokens (75%)Test files

Key Insight: The template library approach combined with framework caching provides 50-60% token reduction while maintaining production-ready boilerplate quality. Early exit patterns provide 94% savings when components already exist.

Phase 1: Framework Detection

#!/bin/bash
# Detect project framework

echo "=== Detecting Framework ==="
echo ""

detect_framework() {
    if [ -f "package.json" ]; then
        if grep -q "\"react\"" package.json; then
            if grep -q "\"next\"" package.json; then
                echo "nextjs"
            else
                echo "react"
            fi
        elif grep -q "\"vue\"" package.json; then
            echo "vue"
        elif grep -q "\"@angular/core\"" package.json; then
            echo "angular"
        elif grep -q "\"svelte\"" package.json; then
            echo "svelte"
        elif grep -q "\"express\"" package.json; then
            echo "express"
        elif grep -q "\"fastify\"" package.json; then
            echo "fastify"
        elif grep -q "\"@nestjs/core\"" package.json; then
            echo "nestjs"
        fi
    elif [ -f "requirements.txt" ]; then
        if grep -q "fastapi" requirements.txt; then
            echo "fastapi"
        elif grep -q "django" requirements.txt; then
            echo "django"
        elif grep -q "flask" requirements.txt; then
            echo "flask"
        fi
    fi
}

FRAMEWORK=$(detect_framework)

if [ -z "$FRAMEWORK" ]; then
    echo "❌ No supported framework detected"
    echo ""
    echo "Supported frameworks:"
    echo "  Frontend: React, Vue, Next.js, Angular, Svelte"
    echo "  Backend: Express, Fastify, NestJS, FastAPI, Django, Flask"
    exit 1
fi

echo "✓ Detected framework: $FRAMEWORK"

# Parse arguments
COMPONENT_NAME="${1:-MyComponent}"
COMPONENT_TYPE="${2:-component}"

echo "  Name: $COMPONENT_NAME"
echo "  Type: $COMPONENT_TYPE"

Phase 2: React Component Boilerplate

// React component with TypeScript
import React, { useState, useEffect } from 'react';
import styles from './${COMPONENT_NAME}.module.css';

/**
 * Props for ${COMPONENT_NAME} component
 */
interface ${COMPONENT_NAME}Props {
  /**
   * Component title
   */
  title?: string;

  /**
   * Additional CSS classes
   */
  className?: string;

  /**
   * Event handler when component is clicked
   */
  onClick?: () => void;
}

/**
 * ${COMPONENT_NAME} component
 *
 * @example
 * ```tsx
 * <${COMPONENT_NAME} title="Hello" onClick={() => console.log('clicked')} />
 * ```
 */
export const ${COMPONENT_NAME}: React.FC<${COMPONENT_NAME}Props> = ({
  title = 'Default Title',
  className,
  onClick,
}) => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Component mounted
    console.log('${COMPONENT_NAME} mounted');

    return () => {
      // Component unmounted
      console.log('${COMPONENT_NAME} unmounted');
    };
  }, []);

  const handleClick = () => {
    setCount((prev) => prev + 1);
    onClick?.();
  };

  return (
    <div className={`${styles.container} ${className || ''}`}>
      <h2>{title}</h2>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default ${COMPONENT_NAME};
/* ${COMPONENT_NAME}.module.css */
.container {
  padding: 1rem;
  border: 1px solid #ddd;
  border-radius: 8px;
}

.container h2 {
  margin: 0 0 1rem 0;
  font-size: 1.5rem;
}

.container button {
  padding: 0.5rem 1rem;
  background-color: #0070f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.container button:hover {
  background-color: #0051cc;
}
// ${COMPONENT_NAME}.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { ${COMPONENT_NAME} } from './${COMPONENT_NAME}';

describe('${COMPONENT_NAME}', () => {
  it('renders with default props', () => {
    render(<${COMPONENT_NAME} />);
    expect(screen.getByText('Default Title')).toBeInTheDocument();
  });

  it('renders with custom title', () => {
    render(<${COMPONENT_NAME} title="Custom Title" />);
    expect(screen.getByText('Custom Title')).toBeInTheDocument();
  });

  it('increments count on button click', () => {
    render(<${COMPONENT_NAME} />);
    const button = screen.getByRole('button', { name: /increment/i });

    expect(screen.getByText('Count: 0')).toBeInTheDocument();
    fireEvent.click(button);
    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });

  it('calls onClick handler when clicked', () => {
    const handleClick = jest.fn();
    render(<${COMPONENT_NAME} onClick={handleClick} />);

    const button = screen.getByRole('button', { name: /increment/i });
    fireEvent.click(button);

    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Phase 3: Next.js Page/Route Boilerplate

// Next.js App Router page
import { Metadata } from 'next';
import { ${COMPONENT_NAME} } from '@/components/${COMPONENT_NAME}';

/**
 * Page metadata
 */
export const metadata: Metadata = {
  title: '${COMPONENT_NAME}',
  description: '${COMPONENT_NAME} page description',
};

/**
 * ${COMPONENT_NAME} page component
 */
export default async function ${COMPONENT_NAME}Page() {
  // Server-side data fetching
  const data = await fetchData();

  return (
    <div>
      <h1>${COMPONENT_NAME}</h1>
      <${COMPONENT_NAME} data={data} />
    </div>
  );
}

/**
 * Fetch data on the server
 */
async function fetchData() {
  // Fetch data from API or database
  const res = await fetch('https://api.example.com/data', {
    next: { revalidate: 3600 }, // Revalidate every hour
  });

  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return res.json();
}
// Next.js API Route
import { NextRequest, NextResponse } from 'next/server';

/**
 * GET /api/${COMPONENT_NAME}
 */
export async function GET(request: NextRequest) {
  try {
    // Get query parameters
    const searchParams = request.nextUrl.searchParams;
    const id = searchParams.get('id');

    // Fetch data
    const data = await fetchData(id);

    return NextResponse.json({
      success: true,
      data,
    });
  } catch (error) {
    console.error('${COMPONENT_NAME} GET error:', error);
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
    );
  }
}

/**
 * POST /api/${COMPONENT_NAME}
 */
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();

    // Validate request body
    if (!body.name) {
      return NextResponse.json(
        { success: false, error: 'Name is required' },
        { status: 400 }
      );
    }

    // Process data
    const result = await createData(body);

    return NextResponse.json({
      success: true,
      data: result,
    }, { status: 201 });
  } catch (error) {
    console.error('${COMPONENT_NAME} POST error:', error);
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
    );
  }
}

Phase 4: Express Route Boilerplate

// Express route handler
import { Router, Request, Response, NextFunction } from 'express';
import { body, param, validationResult } from 'express-validator';

const router = Router();

/**
 * ${COMPONENT_NAME} interface
 */
interface ${COMPONENT_NAME} {
  id: string;
  name: string;
  createdAt: Date;
}

/**
 * GET /api/${COMPONENT_NAME}
 * List all ${COMPONENT_NAME}s
 */
router.get(
  '/',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { page = 1, limit = 10, search } = req.query;

      // Fetch data from database
      const items = await db.${COMPONENT_NAME}.findMany({
        where: search ? { name: { contains: search as string } } : {},
        skip: (Number(page) - 1) * Number(limit),
        take: Number(limit),
      });

      const total = await db.${COMPONENT_NAME}.count();

      res.json({
        data: items,
        pagination: {
          page: Number(page),
          limit: Number(limit),
          total,
          totalPages: Math.ceil(total / Number(limit)),
        },
      });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * GET /api/${COMPONENT_NAME}/:id
 * Get ${COMPONENT_NAME} by ID
 */
router.get(
  '/:id',
  param('id').isUUID(),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.findUnique({
        where: { id: req.params.id },
      });

      if (!item) {
        return res.status(404).json({ error: '${COMPONENT_NAME} not found' });
      }

      res.json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * POST /api/${COMPONENT_NAME}
 * Create new ${COMPONENT_NAME}
 */
router.post(
  '/',
  body('name').isString().trim().isLength({ min: 1, max: 255 }),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.create({
        data: {
          name: req.body.name,
        },
      });

      res.status(201).json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * PUT /api/${COMPONENT_NAME}/:id
 * Update ${COMPONENT_NAME}
 */
router.put(
  '/:id',
  param('id').isUUID(),
  body('name').isString().trim().isLength({ min: 1, max: 255 }),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      const item = await db.${COMPONENT_NAME}.update({
        where: { id: req.params.id },
        data: { name: req.body.name },
      });

      res.json({ data: item });
    } catch (error) {
      next(error);
    }
  }
);

/**
 * DELETE /api/${COMPONENT_NAME}/:id
 * Delete ${COMPONENT_NAME}
 */
router.delete(
  '/:id',
  param('id').isUUID(),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
      }

      await db.${COMPONENT_NAME}.delete({
        where: { id: req.params.id },
      });

      res.status(204).send();
    } catch (error) {
      next(error);
    }
  }
);

export default router;

Phase 5: FastAPI Route Boilerplate

# FastAPI route handler
from fastapi import APIRouter, HTTPException, Query, Path
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
import uuid

router = APIRouter(
    prefix="/api/${COMPONENT_NAME}",
    tags=["${COMPONENT_NAME}"],
)

class ${COMPONENT_NAME}Base(BaseModel):
    """Base ${COMPONENT_NAME} schema"""
    name: str = Field(..., min_length=1, max_length=255)

class ${COMPONENT_NAME}Create(${COMPONENT_NAME}Base):
    """Schema for creating ${COMPONENT_NAME}"""
    pass

class ${COMPONENT_NAME}Update(${COMPONENT_NAME}Base):
    """Schema for updating ${COMPONENT_NAME}"""
    name: Optional[str] = Field(None, min_length=1, max_length=255)

class ${COMPONENT_NAME}InDB(${COMPONENT_NAME}Base):
    """Schema for ${COMPONENT_NAME} in database"""
    id: str
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True

class PaginatedResponse(BaseModel):
    """Paginated response schema"""
    data: List[${COMPONENT_NAME}InDB]
    total: int
    page: int
    page_size: int
    total_pages: int

@router.get("/", response_model=PaginatedResponse)
async def list_${COMPONENT_NAME}s(
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    search: Optional[str] = None,
):
    """
    List all ${COMPONENT_NAME}s with pagination

    Args:
        page: Page number (default: 1)
        page_size: Items per page (default: 10, max: 100)
        search: Optional search query

    Returns:
        Paginated list of ${COMPONENT_NAME}s
    """
    try:
        # Query database
        skip = (page - 1) * page_size
        query = db.query(${COMPONENT_NAME})

        if search:
            query = query.filter(${COMPONENT_NAME}.name.contains(search))

        total = query.count()
        items = query.offset(skip).limit(page_size).all()

        return PaginatedResponse(
            data=items,
            total=total,
            page=page,
            page_size=page_size,
            total_pages=(total + page_size - 1) // page_size,
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/{id}", response_model=${COMPONENT_NAME}InDB)
async def get_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
):
    """
    Get ${COMPONENT_NAME} by ID

    Args:
        id: ${COMPONENT_NAME} unique identifier

    Returns:
        ${COMPONENT_NAME} object

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    return item

@router.post("/", response_model=${COMPONENT_NAME}InDB, status_code=201)
async def create_${COMPONENT_NAME}(
    data: ${COMPONENT_NAME}Create,
):
    """
    Create new ${COMPONENT_NAME}

    Args:
        data: ${COMPONENT_NAME} creation data

    Returns:
        Created ${COMPONENT_NAME} object
    """
    try:
        item = ${COMPONENT_NAME}(
            id=str(uuid.uuid4()),
            name=data.name,
            created_at=datetime.utcnow(),
            updated_at=datetime.utcnow(),
        )
        db.add(item)
        db.commit()
        db.refresh(item)
        return item
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/{id}", response_model=${COMPONENT_NAME}InDB)
async def update_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
    data: ${COMPONENT_NAME}Update = None,
):
    """
    Update ${COMPONENT_NAME}

    Args:
        id: ${COMPONENT_NAME} unique identifier
        data: Update data

    Returns:
        Updated ${COMPONENT_NAME} object

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    update_data = data.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(item, key, value)

    item.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(item)
    return item

@router.delete("/{id}", status_code=204)
async def delete_${COMPONENT_NAME}(
    id: str = Path(..., description="${COMPONENT_NAME} ID"),
):
    """
    Delete ${COMPONENT_NAME}

    Args:
        id: ${COMPONENT_NAME} unique identifier

    Raises:
        HTTPException: 404 if ${COMPONENT_NAME} not found
    """
    item = db.query(${COMPONENT_NAME}).filter(${COMPONENT_NAME}.id == id).first()

    if not item:
        raise HTTPException(status_code=404, detail="${COMPONENT_NAME} not found")

    db.delete(item)
    db.commit()
    return None

Summary

echo ""
echo "=== ✓ Boilerplate Generation Complete ==="
echo ""
echo "📁 Generated files for $FRAMEWORK:"

case $FRAMEWORK in
    react)
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.tsx"
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.module.css"
        echo "  - src/components/${COMPONENT_NAME}/${COMPONENT_NAME}.test.tsx"
        ;;
    nextjs)
        echo "  - app/${COMPONENT_NAME}/page.tsx"
        echo "  - app/api/${COMPONENT_NAME}/route.ts"
        ;;
    express)
        echo "  - src/routes/${COMPONENT_NAME}.routes.ts"
        echo "  - src/controllers/${COMPONENT_NAME}.controller.ts"
        ;;
    fastapi)
        echo "  - app/routes/${COMPONENT_NAME}.py"
        echo "  - app/schemas/${COMPONENT_NAME}.py"
        ;;
esac

echo ""
echo "✓ Includes:"
echo "  - TypeScript/type definitions"
echo "  - Input validation"
echo "  - Error handling"
echo "  - JSDoc/docstrings"
echo "  - Unit tests"
echo ""
echo "🚀 Next steps:"
echo "  1. Review and customize generated code"
echo "  2. Update business logic"
echo "  3. Add database integration"
echo "  4. Run tests: npm test"

Best Practices

Code Quality:

  • Follow framework conventions
  • Include comprehensive types
  • Add proper error handling
  • Write meaningful documentation

Integration Points:

  • /test - Generate tests for boilerplate
  • /scaffold - Complete feature scaffolding
  • /inline-docs - Add documentation

What I'll Actually Do

  1. Detect framework - Identify project type
  2. Parse arguments - Component name and type
  3. Generate boilerplate - Framework-specific code
  4. Include tests - Unit/integration tests
  5. Add documentation - JSDoc/docstrings
  6. Follow conventions - Framework best practices

Important: I will NEVER add AI attribution.

Credits: Boilerplate patterns based on Create React App, Next.js, Express.js, FastAPI, and framework documentation best practices.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cache-strategy

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

sessions-init

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

postman-convert

No summary provided by upstream source.

Repository SourceNeeds Review