Skip to content

feat: allow declarations in the template#18282

Merged
dummdidumm merged 19 commits into
mainfrom
declaration-tags
May 29, 2026
Merged

feat: allow declarations in the template#18282
dummdidumm merged 19 commits into
mainfrom
declaration-tags

Conversation

@dummdidumm

@dummdidumm dummdidumm commented May 24, 2026

Copy link
Copy Markdown
Member

Allows {let/const ...} declarations in all places (and more) where we already allow {@const ...} (which will eventually get deprecated in favor of this new feature).

Closes: #16490

Companion PRs:

Allows `{let/var/const/function ...}` declarations in all places where we already allow `{@const ...}` (which will eventually get deprecated in favor of this new feature).
@changeset-bot

changeset-bot Bot commented May 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a283cf7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@18282

@svelte-docs-bot

Copy link
Copy Markdown

@Conduitry

Copy link
Copy Markdown
Member

I don't remember where I made this comment previously, but I don't think we should allow var. And maybe not function either, at least not as a declaration. What are scoping rules going to be on those?

@dummdidumm

Copy link
Copy Markdown
Member Author

Mhm yeah it might be better now that I'm thinking about it. Main reason that we can't guarantee the scope of the surrounding block. E.g. the if block scope might be different for if-else-chains (either porous because real if-else or not because functions) depending on non-obvious rules.

dummdidumm and others added 3 commits May 26, 2026 13:58
…ot guarantee that the same scoping rules always apply due to our optimizations, and it is kinda harder to reason about anyway + you can model everything with const/let
Comment thread documentation/docs/03-template-syntax/11-declaration-tags.md Outdated
Comment thread packages/svelte/src/compiler/phases/2-analyze/visitors/Identifier.js Outdated
Comment thread packages/svelte/src/compiler/phases/scope.js Outdated
@Rich-Harris

Copy link
Copy Markdown
Member

I think we should disallow semicolons: #18312. Other than that, and the (I'm pretty sure?) leftover FunctionDeclaration code, this looks excellent. Very pleased to finally have this feature

Rich-Harris and others added 3 commits May 28, 2026 21:22
I think we should disallow semicolons in declaration tags, because
syntactic ambiguity is always unfortunate and `;}` (the little-used
'winking grinch' emoticon) looks pretty ugly.

We should _definitely_ remove it from code generated with `print`, even
though it unfortunately requires us to duplicate some of the logic in
the `ts` printer.

@Rich-Harris Rich-Harris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HUGE

@dummdidumm dummdidumm merged commit 59d3a36 into main May 29, 2026
38 of 41 checks passed
@dummdidumm dummdidumm deleted the declaration-tags branch May 29, 2026 12:05
@github-actions github-actions Bot mentioned this pull request May 29, 2026
Rich-Harris pushed a commit that referenced this pull request May 29, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## svelte@5.56.0

### Minor Changes

- feat: allow declarations in the template
([#18282](#18282))

### Patch Changes

- perf: use `createElement` instead of `createElementNS` for HTML
elements ([#18262](#18262))

- perf: store `current_sources` as a `Set` for O(1) membership checks
([#18278](#18278))

- perf: deduplicate identical hoisted templates within a component
([#18320](#18320))

- perf: hoist `rest_props` exclude list as a module-scope `Set`
([#18252](#18252))

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
pheuter added a commit to pheuter/svelte-check-rs that referenced this pull request Jun 2, 2026
Add support for Svelte 5 declaration tags — `{const x = expr}` and
`{let x = expr}` used directly in markup (no `@` prefix), introduced in
Svelte 5.56 (sveltejs/svelte#18282).

- AST: new `DeclarationTag` node + `DeclarationKind { Const, Let }`,
  mirroring the existing `ConstTag`.
- Parser: disambiguate `{const ...}`/`{let ...}` from ordinary
  expressions in `parse_expression_tag` via `peek_declaration_kind`
  (no lexer change — `const` already fires standalone via logos
  max-munch; `let` is matched by Ident text). Supports identifier,
  object `{a, b}`, and array `[a, b]`/`[head, ...tail]` targets
  (the latter via a `Text`-token-starting-with-`[` peek, since the
  lexer has no dedicated `LBracket`). Semicolons inside the tag are
  reported as errors. `{@const}` and `{constFoo}`/`{x}`/`{let}` are
  unaffected.
- Transformer: emit `const x = y;` / `let x = y;` in place, with a
  source mapping anchored to the post-keyword declaration text,
  matching the language-tools svelte2tsx reference.
- Diagnostics: declaration tags stay in the no-op group so runes in
  initializers (e.g. `{let s = $state(0)}`) are not falsely flagged.

Tests: 13 parser unit tests (both kinds, whitespace, object/array
destructuring, disambiguation, `{@const}` regression, semicolon ban,
in-`#each`), 4 parser + 6 transformer snapshots (incl. samples adapted
from language-tools ts-declaration-tag.v5 / declaration-tag-async.v5),
and corpus fixtures covering if/each/await/snippet/element/shadowing,
TS annotations + `$state`, and a must-not-panic invalid fixture.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Variable declarations in markup (replacing {@const ...}

3 participants