Loading...
Automatically compiles and validates Svelte components when they are modified
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/svelte-component-compiler.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/bin/bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Check if this is a Svelte component file\nif [[ \"$FILE_PATH\" == *.svelte ]]; then\n echo \"đĨ Svelte Component Compiler - Validating Svelte component...\"\n echo \"đ Component: $FILE_PATH\"\n \n # Check if file exists\n if [ ! -f \"$FILE_PATH\" ]; then\n echo \"â ī¸ Component file not found: $FILE_PATH\"\n exit 1\n fi\n \n # Check if this is a SvelteKit project\n SVELTEKIT_PROJECT=false\n if [ -f \"svelte.config.js\" ] || [ -f \"vite.config.js\" ] && grep -q \"@sveltejs/kit\" package.json 2>/dev/null; then\n echo \"đ¯ SvelteKit project detected\"\n SVELTEKIT_PROJECT=true\n elif [ -f \"package.json\" ] && grep -q \"svelte\" package.json 2>/dev/null; then\n echo \"⥠Svelte project detected\"\n else\n echo \"âšī¸ No Svelte project configuration found\"\n fi\n \n # Check for required tools\n echo \"đ Checking Svelte toolchain...\"\n \n SVELTE_CHECK_AVAILABLE=false\n if command -v npx >/dev/null 2>&1 && npx svelte-check --version >/dev/null 2>&1; then\n SVELTE_CHECK_AVAILABLE=true\n SVELTE_CHECK_VERSION=$(npx svelte-check --version 2>/dev/null)\n echo \"â
svelte-check available: $SVELTE_CHECK_VERSION\"\n else\n echo \"â ī¸ svelte-check not available - install with: npm install -D @sveltejs/language-server svelte-check\"\n fi\n \n # Component syntax validation\n echo \"\"\n echo \"đ Validating component syntax...\"\n \n # Basic syntax validation\n if grep -q '<script' \"$FILE_PATH\" && grep -q '</script>' \"$FILE_PATH\"; then\n echo \"â
Script block found\"\n \n # Check for TypeScript\n if grep -q '<script lang=[\"']ts[\"']>' \"$FILE_PATH\"; then\n echo \"đ TypeScript detected in component\"\n fi\n fi\n \n if grep -q '<style' \"$FILE_PATH\" && grep -q '</style>' \"$FILE_PATH\"; then\n echo \"â
Style block found\"\n \n # Check for scoped styles\n if grep -q '<style.*scoped' \"$FILE_PATH\"; then\n echo \"đ¯ Scoped styles detected\"\n fi\n fi\n \n # Run svelte-check if available\n if [ \"$SVELTE_CHECK_AVAILABLE\" = true ]; then\n echo \"\"\n echo \"đ Running svelte-check validation...\"\n \n if npx svelte-check --output human --no-tsconfig 2>&1; then\n echo \"â
Svelte component validation passed\"\n else\n echo \"â Svelte component validation failed\"\n echo \"đĄ Check the errors above and fix component issues\"\n fi\n fi\n \n # Component analysis\n echo \"\"\n echo \"đ Component Analysis:\"\n \n # Count component features\n PROPS_COUNT=$(grep -c 'export let' \"$FILE_PATH\" 2>/dev/null || echo 0)\n REACTIVE_COUNT=$(grep -c '\\$:' \"$FILE_PATH\" 2>/dev/null || echo 0)\n STORES_COUNT=$(grep -c 'import.*from.*svelte/store' \"$FILE_PATH\" 2>/dev/null || echo 0)\n \n echo \" âĸ Props: $PROPS_COUNT\"\n echo \" âĸ Reactive statements: $REACTIVE_COUNT\"\n echo \" âĸ Store imports: $STORES_COUNT\"\n \n # Check for common patterns\n if grep -q 'on:click' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ đąī¸ Click handlers detected\"\n fi\n \n if grep -q 'bind:' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ đ Data binding detected\"\n fi\n \n if grep -q '{#if' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ đ Conditional rendering detected\"\n fi\n \n if grep -q '{#each' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ đ List rendering detected\"\n fi\n \n # Accessibility checks\n echo \"\"\n echo \"âŋ Accessibility Analysis:\"\n \n if grep -q 'alt=' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ â
Image alt attributes found\"\n fi\n \n if grep -q 'aria-' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ â
ARIA attributes detected\"\n fi\n \n if grep -q 'role=' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ â
Role attributes found\"\n fi\n \n # Performance suggestions\n echo \"\"\n echo \"⥠Performance Tips:\"\n \n if grep -q 'import.*from.*svelte/transition' \"$FILE_PATH\" 2>/dev/null; then\n echo \" âĸ đŦ Transitions detected - ensure they're necessary\"\n fi\n \n if [ \"$REACTIVE_COUNT\" -gt 5 ]; then\n echo \" âĸ â ī¸ Many reactive statements - consider component splitting\"\n fi\n \n echo \"\"\n echo \"đĄ Svelte Best Practices:\"\n echo \" âĸ Use 'export let' for component props\"\n echo \" âĸ Prefer reactive statements over complex logic in templates\"\n echo \" âĸ Use stores for shared state between components\"\n echo \" âĸ Implement proper accessibility attributes\"\n echo \" âĸ Use SvelteKit for full-stack applications\"\n echo \" âĸ Consider component composition over large single components\"\n \n echo \"\"\n echo \"đ¯ Svelte component validation complete!\"\n \nelse\n echo \"âšī¸ File is not a Svelte component: $FILE_PATH\"\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/svelte-component-compiler.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/bin/bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a Svelte component file
if [[ "$FILE_PATH" == *.svelte ]]; then
echo "đĨ Svelte Component Compiler - Validating Svelte component..."
echo "đ Component: $FILE_PATH"
# Check if file exists
if [ ! -f "$FILE_PATH" ]; then
echo "â ī¸ Component file not found: $FILE_PATH"
exit 1
fi
# Check if this is a SvelteKit project
SVELTEKIT_PROJECT=false
if [ -f "svelte.config.js" ] || [ -f "vite.config.js" ] && grep -q "@sveltejs/kit" package.json 2>/dev/null; then
echo "đ¯ SvelteKit project detected"
SVELTEKIT_PROJECT=true
elif [ -f "package.json" ] && grep -q "svelte" package.json 2>/dev/null; then
echo "⥠Svelte project detected"
else
echo "âšī¸ No Svelte project configuration found"
fi
# Check for required tools
echo "đ Checking Svelte toolchain..."
SVELTE_CHECK_AVAILABLE=false
if command -v npx >/dev/null 2>&1 && npx svelte-check --version >/dev/null 2>&1; then
SVELTE_CHECK_AVAILABLE=true
SVELTE_CHECK_VERSION=$(npx svelte-check --version 2>/dev/null)
echo "â
svelte-check available: $SVELTE_CHECK_VERSION"
else
echo "â ī¸ svelte-check not available - install with: npm install -D @sveltejs/language-server svelte-check"
fi
# Component syntax validation
echo ""
echo "đ Validating component syntax..."
# Basic syntax validation
if grep -q '<script' "$FILE_PATH" && grep -q '</script>' "$FILE_PATH"; then
echo "â
Script block found"
# Check for TypeScript
if grep -q '<script lang=["']ts["']>' "$FILE_PATH"; then
echo "đ TypeScript detected in component"
fi
fi
if grep -q '<style' "$FILE_PATH" && grep -q '</style>' "$FILE_PATH"; then
echo "â
Style block found"
# Check for scoped styles
if grep -q '<style.*scoped' "$FILE_PATH"; then
echo "đ¯ Scoped styles detected"
fi
fi
# Run svelte-check if available
if [ "$SVELTE_CHECK_AVAILABLE" = true ]; then
echo ""
echo "đ Running svelte-check validation..."
if npx svelte-check --output human --no-tsconfig 2>&1; then
echo "â
Svelte component validation passed"
else
echo "â Svelte component validation failed"
echo "đĄ Check the errors above and fix component issues"
fi
fi
# Component analysis
echo ""
echo "đ Component Analysis:"
# Count component features
PROPS_COUNT=$(grep -c 'export let' "$FILE_PATH" 2>/dev/null || echo 0)
REACTIVE_COUNT=$(grep -c '\$:' "$FILE_PATH" 2>/dev/null || echo 0)
STORES_COUNT=$(grep -c 'import.*from.*svelte/store' "$FILE_PATH" 2>/dev/null || echo 0)
echo " âĸ Props: $PROPS_COUNT"
echo " âĸ Reactive statements: $REACTIVE_COUNT"
echo " âĸ Store imports: $STORES_COUNT"
# Check for common patterns
if grep -q 'on:click' "$FILE_PATH" 2>/dev/null; then
echo " âĸ đąī¸ Click handlers detected"
fi
if grep -q 'bind:' "$FILE_PATH" 2>/dev/null; then
echo " âĸ đ Data binding detected"
fi
if grep -q '{#if' "$FILE_PATH" 2>/dev/null; then
echo " âĸ đ Conditional rendering detected"
fi
if grep -q '{#each' "$FILE_PATH" 2>/dev/null; then
echo " âĸ đ List rendering detected"
fi
# Accessibility checks
echo ""
echo "âŋ Accessibility Analysis:"
if grep -q 'alt=' "$FILE_PATH" 2>/dev/null; then
echo " âĸ â
Image alt attributes found"
fi
if grep -q 'aria-' "$FILE_PATH" 2>/dev/null; then
echo " âĸ â
ARIA attributes detected"
fi
if grep -q 'role=' "$FILE_PATH" 2>/dev/null; then
echo " âĸ â
Role attributes found"
fi
# Performance suggestions
echo ""
echo "⥠Performance Tips:"
if grep -q 'import.*from.*svelte/transition' "$FILE_PATH" 2>/dev/null; then
echo " âĸ đŦ Transitions detected - ensure they're necessary"
fi
if [ "$REACTIVE_COUNT" -gt 5 ]; then
echo " âĸ â ī¸ Many reactive statements - consider component splitting"
fi
echo ""
echo "đĄ Svelte Best Practices:"
echo " âĸ Use 'export let' for component props"
echo " âĸ Prefer reactive statements over complex logic in templates"
echo " âĸ Use stores for shared state between components"
echo " âĸ Implement proper accessibility attributes"
echo " âĸ Use SvelteKit for full-stack applications"
echo " âĸ Consider component composition over large single components"
echo ""
echo "đ¯ Svelte component validation complete!"
else
echo "âšī¸ File is not a Svelte component: $FILE_PATH"
fi
exit 0svelte-check reports 'Cannot find module' errors for valid imports
Missing @types or incorrect tsconfig paths. Install: 'npm install --save-dev @sveltejs/vite-plugin-svelte @types/node'. Add to tsconfig: '"types": ["svelte", "vite/client"]' enabling Svelte module resolution.
Hook runs validation on every file save not just .svelte files
Matchers too broad catching all writes/edits. Restrict: 'matchers': ['write:**/*.svelte', 'edit:**/*.svelte'] targeting Svelte components only. Prevents unnecessary checks on JS/TS files.
SvelteKit detection fails despite valid svelte.config.js present
Config check requires both svelte.config.js AND @sveltejs/kit in package.json. Verify: 'grep @sveltejs/kit package.json'. Or simplify: 'if [ -f "svelte.config.js" ]; then SVELTEKIT_PROJECT=true; fi'.
Reactive statement count includes CSS variables with $ prefix
grep '\$:' matches CSS custom properties in <style>. Refine: 'grep -v '<style' file.svelte | grep -c '\$:'' excluding style blocks. Or target: 'grep '<script' -A 100 | grep -c '\$:''.
npx svelte-check slow taking 30+ seconds per component validation
Checks entire project not single file. Remove --no-tsconfig: run full project check on session end not per-file. Or use '--workspace' limiting scope: 'svelte-check --workspace src/components'.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters