svelte-eslint-parser
v1.9.0
Published
Svelte parser for ESLint
Readme
svelte-eslint-parser
Svelte parser for ESLint
Motivation
The svelte-eslint-parser aims to make it easy to create your own ESLint rules for Svelte.
eslint-plugin-svelte is an ESLint plugin built upon this parser, and it already implements some rules.
ESLint Plugins Using svelte-eslint-parser
eslint-plugin-svelte
ESLint plugin for Svelte.
Provides a variety of template-based checks using the Svelte AST.
@intlify/eslint-plugin-svelte
ESLint plugin for internationalization (i18n) in Svelte applications, offering helpful i18n-related rules.
Installation
npm install --save-dev eslint svelte-eslint-parserUsage
ESLint Config (eslint.config.js)
import js from "@eslint/js";
import svelteParser from "svelte-eslint-parser";
export default [
js.configs.recommended,
{
files: [
"**/*.svelte",
"*.svelte",
// Need to specify the file extension for Svelte 5 with rune symbols
"**/*.svelte.js",
"*.svelte.js",
"**/*.svelte.ts",
"*.svelte.ts",
],
languageOptions: {
parser: svelteParser,
},
},
];CLI
eslint "src/**/*.{js,svelte}"Options
The parserOptions for this parser generally match what espree—ESLint's default parser—supports.
For example:
import svelteParser from "svelte-eslint-parser";
export default [
// ...
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
parserOptions: {
sourceType: "module",
ecmaVersion: 2024,
ecmaFeatures: {
globalReturn: false,
impliedStrict: false,
jsx: false,
},
},
},
},
];parserOptions.parser
Use the parserOptions.parser property to define a custom parser for <script> tags. Any additional parser options (besides the parser itself) are passed along to the specified parser.
import tsParser from "@typescript-eslint/parser";
export default [
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsParser,
},
},
},
];Using TypeScript in <script>
If you use @typescript-eslint/parser for TypeScript within <script> of .svelte files, additional configuration is needed. For example:
import tsParser from "@typescript-eslint/parser";
export default [
// Other config for non-Svelte files
{
languageOptions: {
parser: tsParser,
parserOptions: {
project: "path/to/your/tsconfig.json",
extraFileExtensions: [".svelte"],
},
},
},
// Svelte config
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
// Parse the `<script>` in `.svelte` as TypeScript by adding the following configuration.
parserOptions: {
parser: tsParser,
},
},
},
];Using JSDoc types in JavaScript
The configuration above also supports JSDoc type annotations in JavaScript
<script> blocks (with no lang, lang="js", or lang="javascript") and
.svelte.js files. Configure parserOptions.project or
parserOptions.projectService to enable type-aware lint rules.
<script>
/** @param {number} value */
function increment(value) {
return value + 1;
}
</script>
{increment(1)}When using multiple parsers, assign @typescript-eslint/parser to the js
entry as well as ts to enable JSDoc type information in ordinary <script>
blocks. JavaScript configured to use Espree continues to use Espree.
Multiple parsers
To switch parsers for each language, provide an object:
import tsParser from "@typescript-eslint/parser";
import espree from "espree";
export default [
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: {
ts: tsParser,
js: espree,
typescript: tsParser,
},
},
},
},
];parserOptions.svelteConfig
If you use eslint.config.js, you can specify a svelte.config.js file via parserOptions.svelteConfig.
import svelteConfig from "./svelte.config.js";
export default [
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
parserOptions: {
svelteConfig,
},
},
},
];If parserOptions.svelteConfig is not set, the parser attempts to statically read some config from svelte.config.js.
parserOptions.svelteFeatures
You can configure how Svelte-specific features are parsed via parserOptions.svelteFeatures.
For example:
export default [
{
files: [
// Set .svelte/.js/.ts files. See above for more details.
],
languageOptions: {
parser: svelteParser,
parserOptions: {
svelteFeatures: {
// This is for Svelte 5. The default is true.
// If false, ESLint won't recognize rune symbols.
// If not specified, the parser tries to read compilerOptions.runes from `svelte.config.js`.
// If `parserOptions.svelteConfig` is not given and static analysis fails, it defaults to true.
runes: true,
},
},
},
},
];Experimental
ts.sys.readFile hook for type-aware Svelte lint
⚠️ Experimental. Opt-in only; behavior may change or be removed.
Speeds up type-aware lint of .svelte files. Your ESLint config must
already list .svelte via parserOptions.extraFileExtensions.
SVELTE_ESLINT_PARSER_EXPERIMENTAL_TS_SYS_HOOK=1 \
eslint --no-cache --concurrency auto .When enabled, the hook also resolves .svelte import specifiers to the
imported component's virtual module, so type-aware rules see a component's
real prop, event, and slot types across files. import Foo from "./Foo.svelte"
is resolved through a virtual Foo.svelte.ts companion that the hook serves
from the same translation — no tsconfig changes are required. If a real
Foo.svelte.ts (a Svelte runes module) exists on disk, it always takes
precedence and the hook leaves it untouched. In that case component prop types
are not available for that component, because plain TypeScript resolution picks
the module instead of the component. To avoid this name collision, enable the
svelte/no-conflicting-module-names rule from eslint-plugin-svelte (v3.22.0
or later), which reports a Foo.svelte and Foo.svelte.ts pair.
Component typing currently requires a TypeScript <script> and supports
Svelte 3, 4, and 5. Props come from $props() annotations or destructuring
in runes mode, and from $$Props or exported let bindings in legacy mode.
Defaulted props are optional. Explicit $$Events and $$Slots declarations
supply event and slot types; otherwise those types remain permissive.
This is not a full replacement for Svelte's generated component declarations.
Unannotated props without defaults use any, rest props keep the prop type
open, and generic parameters are represented by their constraints rather than
preserving a generic component signature. Instance exports and slot types
inferred from template markup are not synthesized. JavaScript-only components
do not receive this TypeScript translation.
Caveat: rules that read raw TypeScript diagnostics
(program.getSemanticDiagnostics() and friends) report positions inside
the parser's virtual shim — a pre-existing property of type-aware Svelte
lint, not specific to the hook.
Editor Integrations
Visual Studio Code
Use the dbaeumer.vscode-eslint extension provided by Microsoft.
By default, it only targets *.js and *.jsx, so you need to configure .svelte file support. For example, in .vscode/settings.json:
{
"eslint.validate": ["javascript", "javascriptreact", "svelte"]
}Usage for Custom Rules / Plugins
- See AST.md for the AST specification. You can explore it on the Live DEMO.
- This parser generates its own ScopeManager. Check the Live DEMO.
- Several rules are [already implemented] in [
eslint-plugin-svelte], and their source code can be a helpful reference.
Contributing
Contributions are welcome! Please open an issue or submit a PR on GitHub.
For internal details, see internal-mechanism.md.
License
See LICENSE (MIT) for rights and limitations.
