A collection of AST-Grep rules for linting and analyzing Svelte code, with a focus on Svelte 5 best practices and migration patterns.
This repository contains custom AST-Grep rules specifically designed for Svelte applications. These rules help developers:
The rules in this repository require a custom Svelte parser. To set it up:
# Clone the Svelte tree-sitter grammar
git clone https://github.com/tree-sitter-grammars/tree-sitter-svelte
cd tree-sitter-svelte
# Install dependencies
npm install
# Build the parser (adjust extension based on your OS)
# Linux:
npx tree-sitter build -o ../parsers/svelte.so
# macOS:
# npx tree-sitter build -o ../parsers/svelte.dylib
# Windows:
# npx tree-sitter build -o ../parsers/svelte.dll
Note: This relies on the tree-sitter CLI. Installing tree-sitter-cli or using npx is the intended path.
To use these rules with the custom Svelte parser, create an sgconfig.yml file in your project root:
ruleDirs: [rules]
customLanguages:
svelte:
libraryPath: ./parsers/svelte.so # Adjust path as needed
extensions: [svelte]
languageInjections:
- hostLanguage: svelte
rule:
pattern: <script$A>$CODE</script>
injected: ts
This configuration:
rules/ directory<script lang="ts"> blocks as TypeScriptThese rules help identify patterns that should be updated for Svelte 5:
avoid-export-let: Recommends using $props() instead of export let for typed propsavoid-store-auto-sub: Identifies automatic store subscriptions that should use runesavoid-create-event-dispatcher: Suggests alternatives to createEventDispatcheravoid-reactive-label: Recommends $state() over reactive labels ($:)avoid-on-directives: Points out traditional event directives that should use runessvelte-legacy-component: Identifies legacy component usage patternssvelte-legacy-lifecycle: Points out deprecated lifecycle methodssvelte-legacy-slots: Highlights legacy slot usagesvelte-if-block: Identifies Svelte {#if} blockssvelte-else-if: Identifies Svelte {:else if} blockssvelte-else: Identifies Svelte {:else} blockssvelte-each: Identifies Svelte {#each} blockssvelte-each-with-index: Identifies {#each} blocks with index variablessvelte-each-keyed: Identifies keyed {#each} blockssvelte-await-then: Identifies {#await} blocks with {:then} handlerssvelte-await-catch: Identifies {#await} blocks with {:catch} handlersTo run these rules against your Svelte codebase:
# All configured rules (uses sgconfig.yml)
ast-grep scan
# One rule file, whole repo
ast-grep scan --rule rules/avoid-export-let.yml .
# One rule file, a directory
ast-grep scan --rule rules/avoid-export-let.yml src/
# Ad-hoc pattern (no rule file)
ast-grep run --lang svelte -p '{#if $COND}' src
For quick checks without creating rule files:
# Find all {#if} blocks
ast-grep scan --inline-rules '
id: find-if-blocks
language: svelte
rule:
pattern: "{#if $COND}"
' src
For checking code in <script lang="ts"> blocks:
# console.log
ast-grep scan --inline-rules '
id: no-console-log
language: TypeScript
rule:
pattern: console.log($$$)
' src
# any type (broad)
ast-grep scan --inline-rules '
id: no-any
language: TypeScript
rule:
regex: "\\b:any\\b"
' src
# Scan for all legacy patterns (requires sgconfig.yml)
ast-grep scan
# Focus on specific legacy patterns
ast-grep scan --rule rules/avoid-reactive-label.yml src # Find $: reactive labels
ast-grep scan --rule rules/avoid-export-let.yml src # Find export let statements
ast-grep scan --rule rules/avoid-on-directives.yml src # Find on: directives
ast-grep scan --rule rules/avoid-create-event-dispatcher.yml src # Find createEventDispatcher usage
ast-grep scan --rule rules/avoid-store-auto-sub.yml src # Find $store auto-subscriptions
Contributions are welcome! Feel free to:
.yml file in the rules/ directoryid: rule-identifier
message: "Description of the issue"
severity: warning|error|info|hint
language: svelte
rule:
# Rule pattern here
ast-grep scan --rule rules/your-rule.yml