Skip to content

Commit 3e4c16b

Browse files
Merge branch 'main' into fix-spelling
2 parents a2c30e2 + ec7aae4 commit 3e4c16b

File tree

9 files changed

+109
-20
lines changed

9 files changed

+109
-20
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: "What's new in Svelte: June 2025"
3+
description: 'Attachments are the new actions, plus better snippets and classes'
4+
author: Dani Sandoval
5+
authorURL: https://dreamindani.com
6+
---
7+
8+
In addition to advancing the work on Async Svelte, the maintainers have been hard at work introducing long requested features like Attachments.
9+
10+
This month, we'll share a bit about the new API along with a huge showcase of apps/sites built with Svelte...
11+
12+
Let's dive in!
13+
14+
## What's new in Svelte and SvelteKit
15+
16+
- Attachments are essentially a more flexible and modern version of actions. Read more about their use-cases and improvements over actions in the PR ([#1500](https://github.com/sveltejs/svelte/pull/15000)) or in the [Svelte docs](https://svelte.dev/docs/svelte/@attach) (**[email protected]**, **[email protected]**)
17+
- Do you have actions you love and want to use them as attachments? The `fromAction` utility lets you convert actions into attachments (**[email protected]**, [#15933](https://github.com/sveltejs/svelte/pull/15933))
18+
- Generics are now allowed on snippets - improving typing and type hints (**[email protected]**, **[email protected]**, [#15915](https://github.com/sveltejs/svelte/pull/15915))
19+
- The Svelte extension will now allow you to add missing imports on save (**[email protected]**, [#2744](https://github.com/sveltejs/language-tools/pull/2744))
20+
- State fields can now be declared inside class constructors (**[email protected]**, [#15820](https://github.com/sveltejs/svelte/pull/15820))
21+
- Svelte is now XHTML compliant and the new `fragments: 'html' | 'tree'` option adds wider CSP compliance (**[email protected]**, [#15538](https://github.com/sveltejs/svelte/pull/15538))
22+
- Client-side code is now allowed to run at the top-level of universal pages/layouts when SSR is disabled and page options are only boolean or string literals (**[email protected]**, [#13684](https://github.com/sveltejs/kit/pull/13684))
23+
24+
For a full list of bug fixes in Svelte, SvelteKit and its adapters, check out their CHANGELOGs [here](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md) and [here](https://github.com/sveltejs/kit/tree/main/packages).
25+
26+
---
27+
28+
## Community Showcase
29+
30+
### Apps & Sites built with Svelte
31+
32+
- [Whimsy](https://whimsy.rocks/) is a small game engine and a fantasy console for making interactive stories
33+
- [DASHBOT](https://dashbot.jianong.me/) is a 1v1 Space Robot Sprint Battle game for two players - with local and online modes
34+
- [Kraa](https://kraa.io/) is a web-based markdown editor that does things a little differently
35+
- [Shovel AI](https://www.shovel-ai.com/) is a batch tool for interacting with large amounts of a text data with AI models
36+
- [md.uy](https://md.uy/) is a collaborative, local-first, peer-to-peer markdown editor
37+
- [BringYourAI](https://bringyourai.com/) is a browser extension that provides instant codebase context on any AI chat website
38+
- [Joe Malatesta](https://www.joemmalatesta.com/film) figured out a way to present his film photos in a digital environment
39+
- [Notion Avatar](https://notion-avatar-svelte.vercel.app/) is a Notion-style avatar editor with Svelte 5 Runes
40+
- [ORBITS](https://www.orbits.so/) is your second brain for who you know and who you meet
41+
42+
### Learning Resources
43+
44+
_Featuring Svelte Contributors and Ambassadors_
45+
46+
- In case you missed it, [all the videos from Svelte Summit](https://www.youtube.com/playlist?list=PL8bMgX1kyZThKy_B41FQHk_xsHMQouV1Z) are released over the course of the next few days on Svelte Society YouTube. More on how that happened in last month's [blog post](https://svelte.dev/blog/svelte-summit-videos)
47+
- [Svelte Attachments Are Here And They're Awesome](https://www.youtube.com/watch?v=9PREEREiPAE) by Joy of Code
48+
- [SvelteBench](https://khromov.github.io/svelte-bench/benchmark-results-merged.html) (from Stanislav Khromov) shows how different AI models perform out of the box on Svelte 5 syntax - now updated with Anthropic's new Claude 4 models
49+
- [First look at GitHub Copilot Coding Agent - The $40/month AI developer that actually works!](https://www.youtube.com/watch?v=FRcOen6JuJc) by Stanislav Khromov (video)
50+
- [Truly Native Apps with Svelte?](https://mainmatter.com/blog/2025/05/22/native-apps-with-svelte/) by Paolo Ricciuti
51+
52+
_This Week in Svelte_
53+
54+
- [Ep. 102](https://www.youtube.com/watch?v=frp8BXlBAZY) — Svelte+Lynx and Async Svelte
55+
- [Ep. 103](https://www.youtube.com/watch?v=P3Ldkuksqu0) — Attachments
56+
- [Ep. 104](https://www.youtube.com/watch?v=txM-BCrZcbc) — Skeleton v3.0
57+
- [Ep. 105](https://www.youtube.com/watch?v=Tiq0wivUNAE) — Changelog
58+
59+
_To Watch/Read_
60+
61+
- [Svelte's Next Big Change? (server components soon?)](https://www.youtube.com/watch?v=nQB9iRijqBY) by Better Stack
62+
- [I spent some time using Better-Auth and Polar with SvelteKit and this is what I think](https://www.reddit.com/r/sveltejs/comments/1kaiwkk/i_spent_some_time_using_betterauth_and_polar_with/) by elansx
63+
- [Building md.uy - Peer-to-Peer Markdown Editor](https://mr19.xyz/blog/md-uy/) by mateor
64+
65+
### Libraries, Tools & Components
66+
67+
- [Bits UI v2 released](https://www.bits-ui.com) - with support for attachments, `$props.id()`, Shadow DOM, and more
68+
- [Composably](https://github.com/kompismoln/composably) is a content processing plugin for Vite and SvelteKit with typed content + dynamic Svelte components at build time
69+
- [Svelte Flow is now 1.0](https://svelteflow.dev/) - with Svelte 5 support, TSDoc and a bunch of new features to make interactive flow charts even better
70+
- [fox ui](https://flo-bit.dev/ui-kit/) is a collection UI components built with Tailwind 4 and Svelte 5 - now with a [rich text editor](https://www.reddit.com/r/sveltejs/comments/1kjwuci/currently_building_a_svelte_rich_text_editor_on/)
71+
- [fluid-dnd](https://github.com/carlosjorger/fluid-dnd) is a drag and drop library for Vue, React and Svelte
72+
- [sveltekit-password-protect](https://github.com/humanshield-sidepack/sveltekit-password-protect) is a simple utility to add a layer of protection to your websites
73+
- [sveltekit-image-optimize](https://github.com/humanshield-sidepack/sveltekit-image-optimize) is a simple utility that helps you create an endpoint of your svelte app that optimizes your images
74+
- [[email protected] introduces Panels](https://inspect.eirik.space/reference/panel) - a fixed-position resizable panel / drawer that separates the debugging UI from flow of your website
75+
- [nuqs-svelte](https://github.com/rtrampox/nuqs-svelte) is an unnoficial Svelte port of nuqs library - a type-safe search params state manager
76+
- [sv-router](https://sv-router.vercel.app/) is a type-safe SPA router with file-based or code-based routing
77+
- [svelte-textcircle](https://github.com/LoStis-World/svelte-textcircle) displays text in a circular layout with customizable animations and styling
78+
79+
That's it for this month! Let us know if we missed anything on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.gg/svelte).
80+
81+
Until next time 👋🏼!

apps/svelte.dev/content/docs/kit/10-getting-started/25-project-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ You can create a library to be used by other Svelte apps with the [`@sveltejs/pa
4949

5050
## Offline app
5151

52-
SvelteKit has full suppport for [service workers](service-workers) allowing you to build many types of applications such as offline apps and [progressive web apps](glossary#PWA).
52+
SvelteKit has full support for [service workers](service-workers) allowing you to build many types of applications such as offline apps and [progressive web apps](glossary#PWA).
5353

5454
## Mobile app
5555

apps/svelte.dev/content/docs/svelte/02-runes/04-$effect.md

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,11 @@ In general, `$effect` is best considered something of an escape hatch — useful
270270
271271
If you're using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that [deriveds can be directly overridden]($derived#Overriding-derived-values) as of Svelte 5.25.
272272

273-
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/playground/untitled#H4sIAAAAAAAACpVRy26DMBD8FcvKgUhtoIdeHBwp31F6MGSJkBbHwksEQvx77aWQqooq9bgzOzP7mGTdIHipPiZJowOpGJAv0po2VmfnDv4OSBErjYdneHWzBJaCjcx91TWOToUtCIEE3cig0OIty44r5l1oDtjOkyFIsv3GINQ_CNYyGegd1DVUlCR7oU9iilDUcP8S8roYs9n8p2wdYNVFm4csTx872BxNCcjr5I11fdgonEkXsjP2CoUUZWMv6m6wBz2x7yxaM-iJvWeRsvSbSVeUy5i0uf8vKA78NIeJLSZWv1I8jQjLdyK4XuTSeIdmVKJGGI4LdjVOiezwDu1yG74My8PLCQaSiroe5s_5C2PHrkVGAgAA)):
273+
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/playground/untitled#H4sIAAAAAAAAE5WRTWrDMBCFryKGLBJoY3fRjWIHeoiu6i6UZBwEY0VE49TB-O6VxrFTSih0qe_Ne_OjHpxpEDS8O7ZMeIAnqC1hAP3RA1990hKI_Fb55v06XJA4sZ0J-IjvT47RcYyBIuzP1vO2chVHHFjxiQ2pUr3k-SZRQlbBx_LIFoEN4zJfzQph_UMQr4hRXmBd456Xy5Uqt6pPKHmkfmzyPAZL2PCnbRpg8qWYu63I7lu4gswOSRYqrPNt3CgeqqzgbNwRK1A76w76YqjFspfcQTWmK3vJHlQm1puSTVSeqdOc_r9GaeCHfUSY26TXry6Br4RSK3C6yMEGT-aqVU3YbUZ2NF6rfP2KzXgbuYzY46czdgyazy0On_FlLH3F-UDXhgIO35UGlA1rAgAA)):
274274

275275
```svelte
276276
<script>
277-
let total = 100;
277+
const total = 100;
278278
let spent = $state(0);
279279
let left = $state(total);
280280
@@ -298,32 +298,26 @@ You might be tempted to do something convoluted with effects to link one value t
298298
</label>
299299
```
300300

301-
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE51SsW6DMBT8FcvqABINdOhCIFKXTt06lg4GHpElYyz8iECIf69tcIIipo6-u3f3fPZMJWuBpvRzkBXyTpKSy5rLq6YRbbgATdOfmeKkrMgCBt9GPpQ66RsItFjJNBzhVScRJBobmumq5wovhSxQABLskAmSk7ckOXtMKyM22ItGhhAk4Z0R0OwIN-tIQzd-90HVhvy2HsGNiQFCMltBgd7XoecV2xzXNV7XaEcth7ZfRv7kujnsTX2Qd7USb5rFjwZkJlgJwpWRcakG04cpOS9oz-QVCuoeInXW-RyEJL-sG0b7Wy6kZWM-u7CFxM5tdrIl9qg72vB74H-y7T2iXROHyVb0CLanp1yNk4D1A1jQ91hzrQSbUtIIGLcir0ylJDm9Q7urz42bX4UwIk2xH2D5Xf4A7SeMcMQCAAA=)):
301+
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE5VRvW7CMBB-FcvqECQK6dDFJEgsnfoGTQdDLsjSxVjxhYKivHvPBwFUsXS8774_nwftbQva6I_e78gdvNo6Xzu_j3quG4cQtfkaNJ1DIiWA8atkE8IiHgEpYVsb4Rm-O3gCT2yji7jrXKB15StiOJKiA1lUpXrL81VCEUjFwHTGXiJZgiyf3TYIjSxq6NwR6uyifr0ohMbEZnpHH2rWf7ImS8KZGtK6osl_UqelRIyVL5b3ir5AuwWUtoXzoee6fIWy0p31e6i0XMocLfZQDuI6qtaeykGcR7UU6XWznFAZU9LN_X9B2UyVayk9f3ji0-REugen6U9upDOCcAWcLlS7GNCejWoQTqsLtrfBqHzxDu3DrUTOf0xwIm2o62H85sk6_OHG2jQWI4y_3byXXGMCAAA=)):
302302

303303
```svelte
304304
<script>
305-
let total = 100;
305+
const total = 100;
306306
let spent = $state(0);
307-
let left = $state(total);
308-
309-
function updateSpent(value) {
310-
spent = value;
311-
left = total - spent;
312-
}
307+
let left = $derived(total - spent);
313308
314-
function updateLeft(value) {
315-
left = value;
309+
+++ function updateLeft(left) {
316310
spent = total - left;
317-
}
311+
}+++
318312
</script>
319313
320314
<label>
321-
<input type="range" bind:value={() => spent, updateSpent} max={total} />
315+
<input type="range" bind:value={spent} max={total} />
322316
{spent}/{total} spent
323317
</label>
324318
325319
<label>
326-
<input type="range" bind:value={() => left, updateLeft} max={total} />
320+
<input type="range" +++bind:value={() => left, updateLeft}+++ max={total} />
327321
{left}/{total} left
328322
</label>
329323
```

apps/svelte.dev/content/docs/svelte/03-template-syntax/12-bind.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: bind:
55

66
Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent.
77

8-
The general syntax is `bind:property={expression}`, where `expression` is an _lvalue_ (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
8+
The general syntax is `bind:property={expression}`, where `expression` is an [_lvalue_](https://press.rebus.community/programmingfundamentals/chapter/lvalue-and-rvalue/) (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
99

1010
<!-- prettier-ignore -->
1111
```svelte

apps/svelte.dev/content/docs/svelte/05-special-elements/04-svelte-body.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: <svelte:body>
99

1010
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](use) on the `<body>` element.
1111

12-
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the top level of your component and must never be inside a block or element.
12+
As with `<svelte:window>` and `<svelte:document>`, this element may only appear at the top level of your component and must never be inside a block or element.
1313

1414
```svelte
1515
<svelte:body onmouseenter={handleMouseenter} onmouseleave={handleMouseleave} use:someAction />

apps/svelte.dev/content/docs/svelte/07-misc/04-custom-elements.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ When constructing a custom element, you can tailor several aspects by defining `
115115
...
116116
```
117117

118+
> [!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.
119+
118120
## Caveats and limitations
119121

120122
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:

apps/svelte.dev/content/docs/svelte/07-misc/07-v5-migration-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,9 +834,9 @@ Svelte 5 is more strict about the HTML structure and will throw a compiler error
834834

835835
Assignments to destructured parts of a `@const` declaration are no longer allowed. It was an oversight that this was ever allowed.
836836

837-
### :is(...) and :where(...) are scoped
837+
### :is(...), :has(...), and :where(...) are scoped
838838

839-
Previously, Svelte did not analyse selectors inside `:is(...)` and `:where(...)`, effectively treating them as global. Svelte 5 analyses them in the context of the current component. As such, some selectors may now be treated as unused if they were relying on this treatment. To fix this, use `:global(...)` inside the `:is(...)/:where(...)` selectors.
839+
Previously, Svelte did not analyse selectors inside `:is(...)`, `:has(...)`, and `:where(...)`, effectively treating them as global. Svelte 5 analyses them in the context of the current component. As such, some selectors may now be treated as unused if they were relying on this treatment. To fix this, use `:global(...)` inside the `:is(...)/:has(...)/:where(...)` selectors.
840840

841841
When using Tailwind's `@apply` directive, add a `:global` selector to preserve rules that use Tailwind-generated `:is(...)` selectors:
842842

apps/svelte.dev/content/docs/svelte/98-reference/.generated/compile-warnings.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,12 @@ In some situations a selector may target an element that is not 'visible' to the
632632
</style>
633633
```
634634

635+
### custom_element_props_identifier
636+
637+
```
638+
Using a rest element or a non-destructured declaration with `$props()` means that Svelte can't infer what properties to expose when creating a custom element. Consider destructuring all the props or explicitly specifying the `customElement.props` option.
639+
```
640+
635641
### element_implicitly_closed
636642

637643
```

apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-warnings.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,12 @@ In some situations a selector may target an element that is not 'visible' to the
653653
</style>
654654
```
655655

656+
### custom_element_props_identifier
657+
658+
```
659+
Using a rest element or a non-destructured declaration with `$props()` means that Svelte can't infer what properties to expose when creating a custom element. Consider destructuring all the props or explicitly specifying the `customElement.props` option.
660+
```
661+
656662
### element_implicitly_closed
657663

658664
```

0 commit comments

Comments
 (0)