| | |

Biome 25 🧹 HTML and Embedded Languages — CSS, GraphQL, and Vue/Svelte/Astro support

⏱️ Estimated read: 12 min | |

Biome’s support for the languages that live inside the JavaScript file and the languages that wrap the JavaScript is the newest and the most experimental part of the toolchain. The CSS and the GraphQL inside the template literals are the embedded languages, and the Vue, the Svelte, and the Astro are the HTML super languages that contain the HTML, the CSS, and the JavaScript in the single file. The two are the different mechanisms. The embedded snippets are the JavaScript template literals that the Biome parses when the javascript.experimentalEmbeddedSnippetsEnabled option is on . The super languages are the separate parsers that the Biome added in v2.3.0, and the parsers are the experimental .

The support matrix is the honest picture. The CSS and the GraphQL have the full support—the parsing, the formatting, and the linting are the stable, and the CSS has the GritQL plugin support . The HTML has the parsing and the linting stable, and the formatting is the experimental, and the HTML requires the explicit opt-in . The Vue, the Svelte, and the Astro have the parsing, the formatting, and the linting all experimental, and the three require the explicit opt-in . The support is the staged, and the stages are the reason the feature is the careful choice.

Key point: The CSS and the GraphQL are the fully supported, and the embedded snippets in the template literals are the opt-in experimental. The Vue, the Svelte, and the Astro are the experimental HTML super languages, and the three require the html.experimentalFullSupportEnabled opt-in. The Svelte support targets the Svelte 5, and the lint rules across the embedded languages may flag the false positives.


Why the embedded languages need the explicit opt-in

The template-literal problem. A JavaScript file can contain the CSS or the GraphQL inside the css or the styled tag, or the gql or the graphql tag. The Biome’s JavaScript parser sees the template literal as the string, and the embedded language is the invisible. The javascript.experimentalEmbeddedSnippetsEnabled is the mechanism that the Biome parses the embedded language, and the opt-in is the reason the feature is not the default—the parsing is the experimental, and the experimental is the stability risk .

The super-language problem. A Vue or a Svelte or an Astro file contains the HTML, the CSS, and the JavaScript in the single file. The Biome’s HTML parser is the separate parser, and the parser is the experimental. The html.experimentalFullSupportEnabled is the mechanism that the Biome enables the full support, and the opt-in is the reason the feature is not the default—the architecture landed in the v2.3.0, and the formatting and the linting rules must be adjusted .

The false-positive problem. The Biome documentation states the warning: if the html.experimentalFullSupportEnabled is false and the .svelte, the .astro, or the .vue files are linted, the partial support causes the false-positive linting errors. The recommendation is to turn off a few additional rules with the overrides option, and the turn-off is the reason the feature is the careful choice .

The Svelte-version problem. The Biome’s experimental Svelte support targets the Svelte 5. The Svelte 4 and the earlier are not supported. The v2.4.0 added the better support for the language-specific syntax—the control-flow syntax like the {#if}{/if}—and the better support is the reason the majority of the Svelte 5 projects are covered . The newer features, the rare syntax, and the edge cases may not be covered.

The consistency problem. The Biome processes the multiple languages in the same file, and the different per-language configurations can cause the inconsistencies. The example: the JavaScript files use the double quotes and the CSS files use the single quotes, and the HTML-ish file ends up with the mixed quotes. The Biome created the GitHub discussion to understand the problem, and the discussion is the reason the consistency is the open question .


a. The CSS and the GraphQL embedded snippets

The CSS and the GraphQL are the fully supported languages. The parsing, the formatting, and the linting are the stable, and the CSS has the GritQL plugin support . The embedded snippets are the opt-in, and the opt-in is the javascript.experimentalEmbeddedSnippetsEnabled option.

// biome.json — the embedded snippets opt-in
{
  "javascript": {
    "experimentalEmbeddedSnippetsEnabled": true
  }
}

The experimentalEmbeddedSnippetsEnabled: true is the mechanism that the Biome parses the CSS and the GraphQL inside the template literals . The css and the styled tags are the CSS, and the gql and the graphql tags are the GraphQL. The opt-in is the reason the feature is the experimental, and the experimental is the stability risk.

// The embedded CSS snippet
const styles = css`
  .button {
    color: red;
  }
`;

// The embedded GraphQL snippet
const query = gql`
  query GetUser {
    user {
      id
      name
    }
  }
`;

The css tagged template is the CSS, and the gql tagged template is the GraphQL. The Biome’s CSS parser and the GraphQL parser process the content when the opt-in is enabled . The lint rules for the CSS—like the noUnknownUnit and the noMissingVarFunction—and the GraphQL—like the noDuplicatedFields—are the mechanism that the embedded content is the validated .

The CSS and the GraphQL are the separate languages, and the separate languages are the fully supported. The embedded snippets are the mechanism that the JavaScript file contains the CSS or the GraphQL, and the opt-in is the reason the feature is the experimental.


b. The Vue, the Svelte, and the Astro super languages

The Vue, the Svelte, and the Astro are the HTML super languages. The Biome v2.3.0 added the support, and the support is the experimental. The html.experimentalFullSupportEnabled is the mechanism that the Biome enables the full support.

// biome.json — the HTML full support opt-in
{
  "html": {
    "experimentalFullSupportEnabled": true
  }
}

The experimentalFullSupportEnabled: true is the mechanism that the Biome formats and lints the HTML, the CSS, and the JavaScript in the .svelte, the .astro, and the .vue files . The v2.4.0 added the better support for the language-specific syntax, and the v2.5.0 improved the lint rules across the embedded languages . The support is the experimental, and the experimental is the reason the opt-in is the requirement.

<!-- The Svelte file -->
<script>
  let count = 0;
</script>

<button on:click={() => count++}>
  Clicked {count} times
</button>

{#if count > 0}
  <p>The count is positive</p>
{/if}

The Svelte file contains the JavaScript in the <script>, the HTML in the markup, and the Svelte-specific control-flow syntax in the {#if}. The Biome’s Svelte parser processes the three when the opt-in is enabled . The Svelte 5 is the target, and the Svelte 4 and the earlier are not supported.

The overrides option is the mechanism that the partial support’s false positives are the avoided. The example from the documentation:

// biome.json — the overrides for the partial support
{
  "overrides": [
    {
      "includes": ["**/*.svelte", "**/*.astro", "**/*.vue"],
      "linter": {
        "rules": {
          // The rules that cause the false positives are off.
        }
      }
    }
  ]
}

The includes: ["**/*.svelte", "**/*.astro", "**/*.vue"] is the mechanism that the overrides apply to the three file types. The rule off is the mechanism that the false positives are the avoided, and the avoidance is the reason the feature is the usable in the partial state .

The Tailwind integration is the separate improvement. The Biome 2.6 added the Tailwind-aware linting and the class sorting across the HTML, the Vue, the Svelte, and the Astro. The useTailwindSortedClasses and the noTailwindRawColors are the rules, and the rules are the mechanism that the Tailwind classes are the sorted and the design-system colors are the enforced . The integration is the mechanism that the super languages are the useful for the Tailwind project.


Complete Example Session

// ============================================
// PART 1: THE EMBEDDED SNIPPETS OPT-IN
// ============================================

// biome.json
{
  "javascript": {
    "experimentalEmbeddedSnippetsEnabled": true
  }
}

// The CSS and the GraphQL inside the template literals are parsed.

// ============================================
// PART 2: THE EMBEDDED CSS SNIPPET
// ============================================

const styles = css`
  .button {
    color: red;
  }
`;

// The Biome's CSS parser processes the content.

// ============================================
// PART 3: THE EMBEDDED GRAPHQL SNIPPET
// ============================================

const query = gql`
  query GetUser {
    user { id name }
  }
`;

// The Biome's GraphQL parser processes the content.

// ============================================
// PART 4: THE HTML FULL SUPPORT OPT-IN
// ============================================

// biome.json
{
  "html": {
    "experimentalFullSupportEnabled": true
  }
}

// The Vue, the Svelte, and the Astro files are parsed.

// ============================================
// PART 5: THE SVELTE FILE
// ============================================

// The Svelte file contains the HTML, the CSS, and the JavaScript.
// The Svelte 5 is the target.
// The Svelte 4 and the earlier are not supported.

// ============================================
// PART 6: THE OVERRIDES FOR THE PARTIAL SUPPORT
// ============================================

// biome.json
{
  "overrides": [
    {
      "includes": ["**/*.svelte", "**/*.astro", "**/*.vue"],
      "linter": { "rules": { /* the rules off */ } }
    }
  ]
}

// The false positives are the avoided.

// ============================================
// PART 7: THE TAILWIND INTEGRATION
// ============================================

// The useTailwindSortedClasses and the noTailwindRawColors.
// The rules are the mechanism for the Tailwind project.

// ============================================
// PART 8: THE CONSISTENCY PROBLEM
// ============================================

// The JavaScript uses the double quotes and the CSS uses the single.
// The HTML-ish file ends up with the mixed quotes.
// The GitHub discussion is the open question.

// ============================================
// PART 9: THE LANGUAGE SUPPORT MATRIX
// ============================================

// The CSS and the GraphQL: the full support.
// The HTML: the parsing and the linting stable, the formatting experimental.
// The Vue, the Svelte, the Astro: the experimental.

// ============================================
// PART 10: THE CHECKLIST
// ============================================

// [ ] The embedded snippets opt-in is enabled.
// [ ] The CSS and the GraphQL tags are the `css` and the `gql`.
// [ ] The HTML full support opt-in is enabled.
// [ ] The Svelte 5 is the target.
// [ ] The overrides avoid the false positives.
// [ ] The Tailwind integration is the separate improvement.

The ten parts covered the embedded snippets opt-in, the embedded CSS snippet, the embedded GraphQL snippet, the HTML full support opt-in, the Svelte file, the overrides, the Tailwind integration, the consistency problem, the language support matrix, and the checklist. The through-line is that the embedded languages are the opt-in experimental, and the super languages are the experimental.


Quick Reference

The language support stages

LanguageParsingFormattingLintingPlugin
CSSStableStableStableYes
GraphQLStableStableStableNo
HTMLStableExperimentalStableNo
VueExperimentalExperimentalExperimentalNo
SvelteExperimentalExperimentalExperimentalNo
AstroExperimentalExperimentalExperimentalNo

The opt-in options

FeatureOption
The embedded snippetsjavascript.experimentalEmbeddedSnippetsEnabled
The HTML full supporthtml.experimentalFullSupportEnabled

The embedded tags

LanguageTags
CSScss, styled
GraphQLgql, graphql

The limitations

LimitationDetail
The Svelte versionThe Svelte 5 only
The false positivesThe partial support causes them
The consistencyThe mixed quotes in the HTML-ish files

Best Practices

✅ Do This:

// Enable the embedded snippets for the CSS and the GraphQL
{ "javascript": { "experimentalEmbeddedSnippetsEnabled": true } } // ✅
// Enable the HTML full support for the Vue, the Svelte, the Astro
{ "html": { "experimentalFullSupportEnabled": true } }             // ✅
// Use the overrides to avoid the false positives
{ "overrides": [{ "includes": ["**/*.svelte"], "linter": { "rules": {} } }] } // ✅

❌ Don’t Do This:

// Assume the embedded snippets are the default
{ } // the embedded CSS and GraphQL are not parsed                    // ❌
// Assume the Vue, the Svelte, the Astro are the stable
{ } // the super languages require the opt-in                        // ❌

Common Pitfalls

PitfallWhy It HappensFix
The embedded CSS is not formattedThe experimentalEmbeddedSnippetsEnabled is not setSet the option
The Vue file is not parsedThe experimentalFullSupportEnabled is not setSet the option
The Svelte 4 file failsThe Svelte support targets the Svelte 5Upgrade to the Svelte 5
The false positive lint errorThe partial supportUse the overrides to turn off the rule

Real-World Examples

1. The embedded CSS

const styles = css`color: red;`;

2. The embedded GraphQL

const query = gql`query { user { id } }`;

3. The embedded snippets opt-in

{ "javascript": { "experimentalEmbeddedSnippetsEnabled": true } }

4. The HTML full support opt-in

{ "html": { "experimentalFullSupportEnabled": true } }

5. The Svelte file

<script>let count = 0;</script>
<button on:click={() => count++}>{count}</button>

6. The overrides

{ "overrides": [{ "includes": ["**/*.svelte"], "linter": { "rules": {} } }] }

7. The Tailwind sorting

<div class="flex bg-red-500 p-4" />

8. The CSS rule

{ "linter": { "rules": { "css": { "noUnknownUnit": "error" } } } }

9. The GraphQL rule

{ "linter": { "rules": { "graphql": { "noDuplicatedFields": "error" } } } }

10. The consistency problem

The JavaScript and the CSS use the different quotes.

Visual

The Language Support Matrix

┌──────────────────────────────────────────────────────────────┐
│  THE LANGUAGE SUPPORT MATRIX                                 │
│                                                              │
│  CSS:        the full support                                │
│  GraphQL:    the full support                                │
│  HTML:       the parsing and the linting stable,             │
│              the formatting experimental                     │
│  Vue:        the experimental                                │
│  Svelte:     the experimental (the Svelte 5)                 │
│  Astro:      the experimental                                │
└──────────────────────────────────────────────────────────────┘

The Embedded Snippets

┌──────────────────────────────────────────────────────────────┐
│  THE EMBEDDED SNIPPETS                                       │
│                                                              │
│  The JavaScript file                                         │
│  ┌─────────────────────┐                                    │
│  │ const styles =      │  The CSS tag                       │
│  │   css`...`          │                                    │
│  └──────────┬──────────┘                                    │
│             │                                                │
│             ▼                                                    │
│  ┌─────────────────────┐                                    │
│  │ The CSS parser      │  The opt-in required               │
│  └─────────────────────┘                                    │
│                                                              │
│  The GraphQL tag is the same mechanism.                      │
└──────────────────────────────────────────────────────────────┘

The Super Languages

┌──────────────────────────────────────────────────────────────┐
│  THE SUPER LANGUAGES                                         │
│                                                              │
│  The Vue/Svelte/Astro file                                   │
│  ┌─────────────────────┐                                    │
│  │ The HTML            │  The parser                        │
│  │ The CSS             │                                    │
│  │ The JavaScript      │                                    │
│  └──────────┬──────────┘                                    │
│             │                                                │
│             ▼                                                    │
│  ┌─────────────────────┐                                    │
│  │ The opt-in required │  The experimental                  │
│  └─────────────────────┘                                    │
└──────────────────────────────────────────────────────────────┘

Summary

ItemValue
The CSSThe full support
The GraphQLThe full support
The HTMLThe parsing and the linting stable, the formatting experimental
The Vue/Svelte/AstroThe experimental
The embedded snippetsThe opt-in javascript.experimentalEmbeddedSnippetsEnabled
The super languagesThe opt-in html.experimentalFullSupportEnabled
The Svelte versionThe Svelte 5

Key takeaways:

  • The CSS and the GraphQL are the fully supported languages. The parsing, the formatting, and the linting are the stable, and the CSS has the GritQL plugin support. The embedded snippets—the CSS and the GraphQL inside the template literals—are the opt-in experimental, and the javascript.experimentalEmbeddedSnippetsEnabled is the mechanism .
  • The Vue, the Svelte, and the Astro are the experimental super languages. The v2.3.0 added the architecture, and the v2.4.0 improved the language-specific syntax. The html.experimentalFullSupportEnabled is the opt-in, and the opt-in is the reason the feature is not the default .
  • The Svelte support targets the Svelte 5. The Svelte 4 and the earlier are not supported. The v2.4.0 added the control-flow syntax support, and the majority of the Svelte 5 projects are covered .
  • The partial support causes the false positives. The recommendation is to use the overrides to turn off the rules that cause them, and the turn-off is the reason the feature is the usable in the partial state .
  • The consistency problem is the open question. The different per-language configurations can cause the mixed quotes in the HTML-ish files, and the Biome created the GitHub discussion to understand the problem .

Remember: The Biome HTML and the embedded languages are the staged support. The CSS and the GraphQL are the stable, and the embedded snippets are the opt-in experimental. The Vue, the Svelte, and the Astro are the experimental super languages, and the opt-in is the requirement. The Svelte 5 is the target, and the false positives are the partial support’s cost.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!