
Code Antipatterns
- 60 installs
- 49 repo stars
- Updated August 4, 2026
- laurigates/claude-plugins
Helps with ai & agent building tasks.
About
code-antipatterns is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- code-antipatterns
- AI & Agent Building
- AI-coding skill
Code Antipatterns by the numbers
- 60 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #6,460 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/laurigates/claude-plugins --skill code-antipatternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 60 |
|---|---|
| repo stars | ★ 49 |
| Last updated | August 4, 2026 |
| Repository | laurigates/claude-plugins ↗ |
What it does
Helps with ai & agent building tasks.
Files
When to Use This Skill
| Use this skill when... | Use something else instead when... |
|---|---|
| Running a parallel anti-pattern scan and producing a report | Looking up the full YAML rule catalog → see REFERENCE.md |
| Specifically targeting empty catches, floating promises, or `\ | \ |
| Finding success-on-empty / silent degradation patterns | Use the dedicated scanner → code-hidden-failures --track degradation |
| Broad code-quality review across security, perf, and architecture | Run the full review delegate → code-review |
Context
- Analysis path:
$1(defaults to current directory if not specified) - JS/TS files: !
find . -type f \( -name "*.js" -o -name "*.ts" -o -name "*.jsx" -o -name "*.tsx" \) - Vue files: !
find . -name "*.vue" - Python files: !
find . -name "*.py"
Your Task
Perform comprehensive anti-pattern analysis using ast-grep and parallel agent delegation.
Analysis Categories
Based on the detected languages, analyze for these categories:
1. JavaScript/TypeScript Anti-patterns
- Callbacks, magic values, console.logs
- var usage, deprecated patterns
- Error swallowing (empty catch, floating promises) → delegate to
/code:hidden-failures --track errors
2. Async/Promise Patterns
- Nested callbacks, Promise constructor anti-pattern
- Error-handling coverage (unhandled/floating promises) → delegate to
/code:hidden-failures --track errors
3. Framework-Specific (if detected)
- Vue 3: Props mutation, reactivity issues, Options vs Composition API mixing
- React: Missing deps in hooks, inline functions, prop drilling
4. TypeScript Quality (if .ts files present)
- Excessive
anytypes, non-null assertions, type safety issues
5. Code Complexity
- Long functions (>50 lines), deep nesting (>4 levels), large parameter lists
6. Security Concerns
- eval usage, innerHTML XSS, hardcoded secrets, injection risks
7. Memory & Performance
- Event listeners without cleanup, setInterval leaks, inefficient patterns
8. Python Anti-patterns (if detected)
- Mutable default arguments, global variables
- Bare except and suppression patterns → delegate to
/code:hidden-failures --track errors
Delegated Category: Error Swallowing
Do NOT re-implement empty-catch / bare-except / floating-promise detection here. Invoke /code:hidden-failures --track errors via the SlashCommand tool with the same PATH and severity filter, then fold its findings into the consolidated report under a dedicated Error Swallowing section.
Rationale: a single source of truth prevents drift between severity models, app-context surfacing recommendations, and privacy redaction policies. See code-quality-plugin/skills/code-hidden-failures/SKILL.md.
Execution Strategy
CRITICAL: Use parallel agent delegation for efficiency.
Launch multiple specialized agents simultaneously:
## Agent 1: Language Detection & Setup (Explore - quick)
Detect project stack, identify file patterns, establish analysis scope
## Agent 2: JavaScript/TypeScript Analysis (code-analysis)
- Use ast-grep for structural pattern matching
- Focus on: magic values, var usage, deprecated patterns
- Error swallowing handled separately via `/code:hidden-failures --track errors`
## Agent 3: Async/Promise Analysis (code-analysis)
- Nested callbacks, Promise constructor anti-pattern
- Floating promises / unhandled rejections handled via `/code:hidden-failures --track errors`
## Agent 4: Framework-Specific Analysis (code-analysis)
- Vue: props mutation, reactivity issues
- React: hooks dependencies, inline functions
## Agent 5: Security Analysis (security-audit)
- eval, innerHTML, hardcoded secrets, injection risks
- Use OWASP context
## Agent 6: Complexity Analysis (code-analysis)
- Function length, nesting depth, parameter counts
- Cyclomatic complexity indicatorsast-grep Pattern Examples
For the full YAML rule catalog (with id:, severity:, message:, fix:, and note: fields), see REFERENCE.md.
Use these patterns during analysis:
# Magic numbers
ast-grep -p 'if ($VAR > 100)' --lang js
# Console statements
ast-grep -p 'console.log($$$)' --lang js
# var usage
ast-grep -p 'var $VAR = $$$' --lang js
# TypeScript any
ast-grep -p ': any' --lang ts
ast-grep -p 'as any' --lang ts
# Vue props mutation
ast-grep -p 'props.$PROP = $VALUE' --lang js
# Security: eval
ast-grep -p 'eval($$$)' --lang js
# Security: innerHTML
ast-grep -p '$ELEM.innerHTML = $$$' --lang js
# Python: mutable defaults
ast-grep -p 'def $FUNC($ARG=[])' --lang pyOutput Format
Consolidate findings into this structure:
## Anti-pattern Analysis Report
### Summary
- Total issues: X
- Critical: X | High: X | Medium: X | Low: X
- Categories with most issues: [list]
### Critical Issues (Fix Immediately)
| File | Line | Issue | Category |
|------|------|-------|----------|
| ... | ... | ... | ... |
### High Priority Issues
| File | Line | Issue | Category |
|------|------|-------|----------|
| ... | ... | ... | ... |
### Medium Priority Issues
[Similar table]
### Low Priority / Style Issues
[Similar table or summary count]
### Recommendations
1. [Prioritized fix recommendations]
2. [...]
### Category Breakdown
- **Security**: X issues (details)
- **Async/Promises**: X issues (details)
- **Code Complexity**: X issues (details)
- [...]Optional Flags
--focus <category>: Focus on specific category (security, async, complexity, framework)--severity <level>: Minimum severity to report (critical, high, medium, low)--fix: Attempt automated fixes where safe
Post-Analysis
After consolidating findings: 1. Prioritize issues by impact and effort 2. Suggest which issues can be auto-fixed with ast-grep 3. Identify patterns that indicate systemic problems 4. Recommend process improvements (linting rules, pre-commit hooks)
See Also
- Reference: REFERENCE.md - Full YAML rule catalog with ast-grep pattern library
- Skill:
ast-grep-search- ast-grep usage reference - Command:
/code:review- Comprehensive code review - Agent:
security-audit- Deep security analysis - Agent:
code-refactoring- Automated refactoring
Related Configure Skills
- If linting not configured →
/configure:lintingfor automated enforcement - If security scanning not set up →
/configure:securityfor CI integration
Code Anti-patterns Reference
Comprehensive ast-grep pattern library for detecting anti-patterns across languages.
JavaScript/TypeScript Patterns
Async Anti-patterns
# Unhandled Promise - missing catch
id: unhandled-promise
language: JavaScript
severity: high
message: Promise chain missing error handler
rule:
pattern: $EXPR.then($HANDLER)
not:
follows:
pattern: .catch($$$)
note: Add .catch() or use try/catch with await
---
# Promise constructor anti-pattern
id: promise-constructor-antipattern
language: JavaScript
severity: medium
message: Unnecessary Promise wrapper around async code
rule:
pattern: new Promise(($RESOLVE, $REJECT) => { $ASYNC_CALL.then($$$) })
fix: $ASYNC_CALL
---
# Floating promise (missing await)
id: floating-promise
language: TypeScript
severity: high
message: Promise result not awaited or handled
rule:
pattern: $ASYNC_FUNC($$$)
not:
any:
- inside:
pattern: await $$$
- inside:
pattern: return $$$
- inside:
pattern: $VAR = $$$Error Handling
# Empty catch block
id: no-empty-catch
language: JavaScript
severity: warning
message: Empty catch block silently swallows errors
rule:
pattern: try { $$$ } catch ($E) { }
fix: |
try { $$$ } catch ($E) {
console.error($E);
throw $E;
}
---
# Catch without error parameter
id: catch-without-error
language: JavaScript
severity: info
message: Consider logging the caught error
rule:
pattern: catch { $$$ }
---
# Generic error catch
id: generic-error-catch
language: TypeScript
severity: info
message: Consider catching specific error types
rule:
pattern: catch ($E: Error) { $$$ }Code Smell Patterns
# Magic numbers
id: no-magic-numbers
language: JavaScript
severity: info
message: Consider extracting magic number to named constant
rule:
any:
- pattern: if ($VAR > 100)
- pattern: if ($VAR < 50)
- pattern: if ($VAR === 42)
- pattern: setTimeout($$$, 5000)
- pattern: setInterval($$$, 1000)
constraints:
# Exclude common acceptable values
VAR:
not:
regex: '^(0|1|-1|100)$'
---
# Long parameter list
id: long-parameter-list
language: JavaScript
severity: medium
message: Consider using an options object for many parameters
rule:
pattern: function $NAME($A, $B, $C, $D, $E, $$$) { $$$ }
note: Functions with more than 4 parameters are hard to use correctly
---
# Nested ternary
id: no-nested-ternary
language: JavaScript
severity: medium
message: Nested ternary is hard to read
rule:
pattern: $A ? $B : $C
has:
pattern: $X ? $Y : $ZDeprecated Patterns
# var usage
id: no-var
language: JavaScript
severity: info
message: Use let or const instead of var
rule:
pattern: var $VAR = $$$
fix: const $VAR = $$$
---
# arguments object
id: no-arguments
language: JavaScript
severity: info
message: Use rest parameters instead of arguments
rule:
pattern: arguments[$INDEX]
---
# Function constructor
id: no-function-constructor
language: JavaScript
severity: error
message: Function constructor is equivalent to eval
rule:
pattern: new Function($$$)Vue 3 Patterns
Reactivity Issues
# Props mutation
id: vue-props-mutation
language: JavaScript
severity: error
message: Never mutate props directly
rule:
pattern: props.$PROP = $VALUE
note: |
Use emit('update:propName', value) or create a local copy:
const localProp = ref(props.propName)
---
# Destructuring reactive state
id: vue-reactive-destructure
language: JavaScript
severity: high
message: Destructuring reactive state loses reactivity
rule:
pattern: const { $$$PROPS } = $REACTIVE_VAR
inside:
pattern: const $REACTIVE_VAR = reactive($$$)
fix: const { $$$PROPS } = toRefs($REACTIVE_VAR)
---
# Watch without immediate or deep when needed
id: vue-watch-options
language: JavaScript
severity: info
message: Consider if watch needs immediate or deep options
rule:
pattern: watch($SOURCE, $CALLBACK)
not:
has:
pattern: watch($SOURCE, $CALLBACK, { $$$ })Composition API Patterns
# Missing onUnmounted cleanup
id: vue-missing-cleanup
language: JavaScript
severity: medium
message: Event listener should be cleaned up in onUnmounted
rule:
pattern: onMounted(() => { $TARGET.addEventListener($$$) })
not:
inside:
has:
pattern: onUnmounted(() => { $TARGET.removeEventListener($$$) })
---
# Computed with side effects
id: vue-computed-side-effect
language: JavaScript
severity: high
message: Computed properties should not have side effects
rule:
pattern: computed(() => { $$$ })
has:
any:
- pattern: console.log($$$)
- pattern: $VAR = $VALUE
- pattern: $OBJ.$PROP = $VALUE
- pattern: fetch($$$)React Patterns
Hooks Issues
# useEffect with empty deps but using state
id: react-missing-deps
language: JavaScript
severity: high
message: useEffect uses variables not in dependency array
rule:
pattern: useEffect(() => { $$$ }, [])
note: Add used variables to dependency array or use exhaustive-deps lint rule
---
# useState with object instead of useReducer
id: react-complex-state
language: JavaScript
severity: info
message: Consider useReducer for complex state objects
rule:
pattern: useState({ $$$PROPS })
has:
pattern: { $A, $B, $C, $D, $$$ }
---
# Inline function in JSX
id: react-inline-function
language: JavaScript
severity: info
message: Inline functions create new references on each render
rule:
any:
- pattern: <$COMP onClick={() => $$$} />
- pattern: <$COMP onChange={() => $$$} />
- pattern: <$COMP onSubmit={() => $$$} />
note: Use useCallback or extract to a named functionComponent Patterns
# Component without memo for expensive renders
id: react-missing-memo
language: JavaScript
severity: info
message: Consider React.memo for components receiving object props
rule:
pattern: function $Component({ $$$PROPS }) { $$$ }
not:
inside:
pattern: memo($$$)
---
# Prop drilling (props passed through multiple levels)
id: react-prop-drilling
language: JavaScript
severity: info
message: Consider Context or state management for deeply passed props
rule:
pattern: <$Child $PROP={props.$PROP} />Python Patterns
Common Anti-patterns
# Mutable default argument
id: py-mutable-default
language: Python
severity: high
message: Mutable default argument creates shared state between calls
rule:
any:
- pattern: def $FUNC($ARG=[])
- pattern: def $FUNC($ARG={})
- pattern: def $FUNC($ARG=set())
fix: |
def $FUNC($ARG=None):
if $ARG is None:
$ARG = []
---
# Bare except
id: py-bare-except
language: Python
severity: high
message: Bare except catches all exceptions including KeyboardInterrupt
rule:
pattern: except:
fix: except Exception:
---
# Global variable
id: py-no-global
language: Python
severity: medium
message: Global variables make code hard to test and reason about
rule:
pattern: global $VAR
---
# Type ignore without reason
id: py-type-ignore-comment
language: Python
severity: info
message: type: ignore should include a reason
rule:
regex: '# type: ignore$'Pythonic Issues
# Using type() instead of isinstance()
id: py-use-isinstance
language: Python
severity: info
message: Use isinstance() for type checking
rule:
pattern: type($VAR) == $TYPE
fix: isinstance($VAR, $TYPE)
---
# Manual iteration with index
id: py-enumerate
language: Python
severity: info
message: Use enumerate() instead of manual index tracking
rule:
pattern: |
for $I in range(len($LIST)):
$$$ = $LIST[$I]
note: Use 'for i, item in enumerate(list):' instead
---
# Not using with statement for files
id: py-file-context
language: Python
severity: medium
message: Use context manager (with statement) for file operations
rule:
pattern: $VAR = open($$$)
not:
inside:
pattern: with open($$$) as $VAR:Security Patterns
Injection Risks
# eval usage
id: no-eval
language: JavaScript
severity: critical
message: eval() is a security risk - never use with user input
rule:
any:
- pattern: eval($$$)
- pattern: new Function($$$)
- pattern: setTimeout($STRING, $$$)
- pattern: setInterval($STRING, $$$)
constraints:
STRING:
kind: string
---
# innerHTML XSS
id: no-innerhtml
language: JavaScript
severity: high
message: innerHTML can lead to XSS - use textContent or sanitize
rule:
any:
- pattern: $ELEM.innerHTML = $$$
- pattern: $ELEM.outerHTML = $$$
---
# SQL injection (string concatenation)
id: sql-injection
language: JavaScript
severity: critical
message: Use parameterized queries instead of string concatenation
rule:
any:
- pattern: '"SELECT * FROM " + $VAR'
- pattern: '"SELECT " + $$$ + " FROM"'
- pattern: '`SELECT * FROM ${$VAR}`'
- pattern: '"INSERT INTO " + $VAR'
- pattern: '"UPDATE " + $VAR'
- pattern: '"DELETE FROM " + $VAR'
---
# Command injection
id: command-injection
language: JavaScript
severity: critical
message: Use execFile with array arguments instead of exec with string
rule:
pattern: exec($COMMAND)
inside:
kind: call_expression
constraints:
COMMAND:
any:
- kind: template_string
- kind: binary_expressionSecrets and Credentials
# Hardcoded API keys
id: hardcoded-api-key
language: JavaScript
severity: critical
message: Never hardcode API keys - use environment variables
rule:
any:
- pattern: apiKey = '$$$'
- pattern: "apiKey: '$$$'"
- pattern: API_KEY = '$$$'
- pattern: 'x-api-key': '$$$'
constraints:
# Exclude empty strings and placeholders
$$$:
not:
regex: '^(|your-api-key|xxx|placeholder)$'
---
# Hardcoded passwords
id: hardcoded-password
language: JavaScript
severity: critical
message: Never hardcode passwords
rule:
any:
- pattern: password = '$$$'
- pattern: "password: '$$$'"
- pattern: pwd = '$$$'
- pattern: secret = '$$$'
---
# JWT secret hardcoded
id: hardcoded-jwt-secret
language: JavaScript
severity: critical
message: JWT secrets should come from environment variables
rule:
pattern: jwt.sign($$$, '$SECRET', $$$)Performance Patterns
Memory Leaks
# Event listener without cleanup
id: event-listener-leak
language: JavaScript
severity: medium
message: Event listener may cause memory leak without removal
rule:
pattern: addEventListener($EVENT, $HANDLER)
not:
inside:
has:
pattern: removeEventListener($EVENT, $HANDLER)
---
# setInterval without cleanup
id: interval-leak
language: JavaScript
severity: medium
message: setInterval should be cleared to prevent memory leaks
rule:
pattern: setInterval($$$)
not:
inside:
has:
pattern: clearInterval($$$)
---
# Closure over large objects
id: closure-memory
language: JavaScript
severity: info
message: Closure captures entire scope - consider extracting needed values
rule:
pattern: |
const $LARGE = $$$;
$$$ = () => { $$$ }Inefficient Patterns
# Array method chaining creating intermediate arrays
id: array-chain-performance
language: JavaScript
severity: info
message: Chained array methods create intermediate arrays - consider reduce
rule:
pattern: $ARR.filter($$$).map($$$)
note: For large arrays, consider using a single reduce() instead
---
# Synchronous file operations
id: sync-file-ops
language: JavaScript
severity: medium
message: Synchronous file operations block the event loop
rule:
any:
- pattern: fs.readFileSync($$$)
- pattern: fs.writeFileSync($$$)
- pattern: fs.existsSync($$$)
note: Use async versions with await or callbacks in productionRunning Multiple Rules
Create sgconfig.yml
ruleDirs:
- rules/javascript
- rules/typescript
- rules/vue
- rules/react
- rules/python
- rules/security
utilDirs:
- rules/utils
testConfigs:
testDir: tests
snapshotDir: __snapshots__
languageGlobs:
- language: TypeScript
extensions: [ts, tsx]
- language: JavaScript
extensions: [js, jsx, mjs, cjs]
- language: Python
extensions: [py]
- language: Vue
extensions: [vue]Run All Rules
# Scan with all rules
ast-grep scan
# Scan specific rule
ast-grep scan -r no-empty-catch
# Output as JSON for processing
ast-grep scan --json > antipatterns-report.json
# Filter by severity
ast-grep scan --json | jq '[.[] | select(.severity == "critical" or .severity == "high")]'Quick Reference Commands
JavaScript/TypeScript
# All anti-patterns
ast-grep -p 'console.log($$$)' --lang js
ast-grep -p 'var $VAR = $$$' --lang js
ast-grep -p 'try { $$$ } catch ($E) { }' --lang js
ast-grep -p 'eval($$$)' --lang js
ast-grep -p ': any' --lang ts
ast-grep -p '$VAR!' --lang tsVue
ast-grep -p 'props.$PROP = $VALUE' --lang js
ast-grep -p 'const { $$$PROPS } = reactive($$$)' --lang jsPython
ast-grep -p 'def $FUNC($ARG=[])' --lang py
ast-grep -p 'except:' --lang py
ast-grep -p 'global $VAR' --lang pySecurity
ast-grep -p 'eval($$$)' --lang js
ast-grep -p '$ELEM.innerHTML = $$$' --lang js
ast-grep -p 'apiKey = "$$$"' --lang js
ast-grep -p '"SELECT * FROM " + $VAR' --lang js