GitShow/sveltejs/svelte
sveltejs

svelte

web development for the rest of us

by sveltejs
compilertemplateui
Star on GitHubForkWebsitenpm

JavaScript

88.0k stars5.2k forks943 contributorsActive · 10h agoSince 2016svelte@5.56.9MIT

Meet the team

See all 943 on GitHub →
Rich-Harris
Rich-Harris5.2k contributions
Conduitry
Conduitry805 contributions
dummdidumm
dummdidumm800 contributions
github-actions[bot]Bot
github-actions[bot]632 contributions
trueadm
trueadm497 contributions
tanhauhau
tanhauhau324 contributions
paoloricciuti
paoloricciuti250 contributions
benmccann
benmccann246 contributions

Languages

View on GitHub →
JavaScript71%
Svelte22.3%
TypeScript4.8%
CSS1.1%
HTML0.8%

Commit activity

Last 12 weeks · 96 commits

Full graph →

Community health

6 of 6 standards met

Community profile →
87
✓README✓License✓Contributing✓Code of Conduct✓Issue Template✓PR Template

Recent PRs & issues

Active · Last activity 10h ago
See all on GitHub →
Ivaneyko
esrap 2.3.3: server codegen emits invalid JS when `@type` JSDoc on `export let` meets a `$:` declarationOpenIssue

Correction (edited shortly after filing):** the trigger is 2.3.3, not a Svelte version. The original text bisected over Svelte releases, which was confounded — each install resolved a different transitive . Details below. Describe the bug With 2.3.3, emits syntactically invalid JavaScript when a comment sits on an prop and the component also has a declaration. The hoisted declaration for the reactive variable now has its declarator wrapped in parentheses, which is not legal after : V8 rejects it with , oxc/rolldown with — since cannot start a declaration here, it parses as an identifier reference, which is reserved in strict mode/modules. is unaffected, so this only surfaces in SSR builds. Because depends on , a fresh resolves 2.3.3 and any project of this shape starts failing to build with no change on its own side. is one concrete path in: its package entry re-exports as the default export, so the component enters the module graph from every and fails to parse even though it is never rendered. Reproduction : Both ingredients are required, and the trigger is specifically . Removing the line, or using , , , , , a non-JSDoc block, or comments, all produce valid output. Version boundary Pinning through with held fixed, on a clean each time: Independent of the Svelte version — 5.56.1 and 5.56.9 are both ok on esrap 2.3.2 and both broken on 2.3.3. This may belong in rather than here; filing where it surfaces. Stack Severity annoyance — the compiler produces invalid output silently rather than erroring, so it surfaces as a bundler parse error in an unrelated file.

Ivaneyko · 10h ago

Recent fixes

View closed PRs →
maarten-nem
set_attributes nulls its own $$-prefixed listener bookkeeping, leaking a listener per toggle for spread on* handlers that go function -> undefinedClosedIssue

Describe the bug When an element receives spread attributes () and one of the spread keys is a non-delegated handler whose value toggles between a function and , Svelte attaches a real and then fails to remove it. One listener leaks per toggle cycle, unbounded for the element's lifetime, and every leaked listener throws on each subsequent event. Capture-phase handlers are the common way to hit this, because is called with the un-stripped name — → , which is not in — so a capture click handler is never delegated even though plain is. Mechanism keeps the attached listener in a -prefixed sibling key of the same long-lived bag: The normalisation loop at the top of every call does not skip keys: A consumer's spread never contains , so once the listener exists every later pass injects that null. The main loop then reaches the key and clears the slot before the guard meant to protect it: The removal branch later calls with , which the DOM spec defines as a no-op. The listener stays attached forever. Enumeration order matters: the normalisation loop appends to , so reaches first and the key last. That is why the very first cycle can still remove correctly — see the trace below. Reproduction : Driver (vitest + jsdom). The listener registry is keyed on the full DOM quadruple . This is essential: the defect is a , so a registry that omits the callback from its key would match that null-callback removal against a live entry, decrement, and report zero leaks. Measured result Every error is : Per-pass trace — an intervening pass is NOT required Live capture-click count recorded after every flush, N = 3: Both shapes leak; only the first cycle differs. On cycle 0 of a bare flip has no key yet, so the normalisation loop injects nothing and the removal reads a still-live slot. From cycle 1 on, the slot is re-injected and nulled inside the same pass that attached the listener. Suggested fix Skip keys in the normalisation loop, or move the existing guard above the assignment: Versions Svelte 5.56.8 (the latest release as of 2026-08-02) vitest 4.1.7 + jsdom, Node 24.18.0 Upstream re-checked 2026-08-02 and still unfixed: the last commit touching is (2026-05-31, "fix: set input type before spread value (#18345)"), which predates the 5.56.8 release. The relevant lines are byte-identical to the installed copy. Possibly related (both closed, both different) sveltejs/svelte#15081 — nullish handler on the compiled, non-spread path (fixed by #15087) sveltejs/svelte#14539 — handler still running after removal from spread props

maarten-nem · 10h ago
subotac
fix: remove stale capture listeners from spread attributesMergedPR

Fixes #18608. When normalized removed spread attributes, it also copied its internal listener bookkeeping keys into with a value. This cleared the stored callback before event cleanup, so removing a capture handler passed to and left the listener attached. Skip internal keys during missing-attribute normalization. The updated runtime-runes sample verifies replacing and then removing a spread capture handler in both client and hydration modes. ### Before submitting the PR, please make sure you do the following [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs [x] Prefix your PR title with , , , or . [x] This message body should clearly illustrate what problems it solves. [x] Ideally, include a test that fails without this PR but passes with it. [x] If this PR changes code within , add a changeset (). ### Tests and linting [ ] Run the tests with and lint the project with Test plan: — 2 passed from — passed Prettier and ESLint on the changed files — passed — passed Four full-suite runs reached 7,664–7,666 passed and 69 skipped. The remaining failures varied between unchanged 30-second runtime/signals timeouts and one unchanged Windows/Chromium layout test. The timeout cases pass in isolation; the layout failure reproduces independently with the local headless browser returning a zero layout width. completed ESLint successfully, then repo-wide Prettier reported line-ending differences in 3,747 unchanged files from the Windows checkout. All changed files pass the scoped Prettier check.

subotac · 10h ago
simiraaaa
Wrong $state value in effect teardown when the state was written multiple times in one flushClosedIssue

Describe the bug When an teardown reads a that was written more than once during the flush that destroys the effect, it receives a value that is neither the value the effect ran with, nor the current value — it is "the value from just before the last write", which is essentially arbitrary. (in ) is overwritten on every write in a flush: and (in ) serves it to any read that happens while is true: Since the map holds only one slot per source, the value handed to a teardown depends on how many writes happened before it in the same flush — not on what the effect actually saw. I understand the "teardowns see old values" behaviour is intentional (#15469, and #18391/#18402 treat it as the contract). This report is not asking to change that contract — it is asking that the value served actually be the old value the effect ran with. Today it is not. This silently breaks any teardown that has to pair up with its effect body — register/unregister, add/remove listener keyed by a value, acquire/release: Click the button once. The effect registered . The teardown is handed *** — a value the effect never observed, and not the current value () either. is a no-op, so leaks in the registry forever. Adding a fourth write () to the handler changes the value handed to the teardown to — it is purely a function of write count. With a single write in the handler everything pairs up correctly, which is why this goes unnoticed until a handler happens to touch the same source twice. I intend to submit a PR for this. Real-world impact This was found via a reference-counting scroll lock: a module-scope counter incremented in effect bodies and decremented in the teardowns. When one effect's teardown runs in the same flush as other effects' increments, the teardown applies its decrement to a stale count and the counter permanently drifts, so the lock is never released ( stays on iOS Safari). That scenario also involves the "teardowns see old values" contract itself, so I will follow it up as a comment in #16019 instead of here. Workaround Snapshot the state into a local in the effect body, and have the teardown use the snapshot instead of re-reading the state (REPL: https://svelte.dev/playground/e966296fb0b4435d9c8f78d77f3f9299?version=5.56.8): The teardown then always deletes exactly what the effect added. Related #15469 introduced (teardowns read pre-write values). This report accepts that contract; it only points out that the stored value is not well-defined when a source is written more than once per flush. #16019 / #16140 debate whether the contract itself should change — orthogonal to this. (I read the whole #16019 thread: multiple writes per flush are not discussed there.) #17375 is a closely related open report (stale in ); the mechanism is the same map. #18391 / #18402 concern being called too early; also the same map, different failure mode. Note: English is not my first language, so I used AI assistance to write this report. The reproductions and logs are from real runs that I verified myself. Reproduction https://svelte.dev/playground/bb8ba4d8027d4f6f8682df63c12c2ddd?version=5.56.8 Same code as in the description; click "go" once and check the console (logs in the Logs field below). The page also shows the leaked key: . Note: the reproduction deliberately renders the state with plain text interpolation. Putting it behind an makes the bug disappear, because a block effect lands in and then calls mid-flush (that early clear is #18391's territory). Also reproduces as a test in the repo (included in the PR), so it is not browser-specific. Logs Severity annoyance

simiraaaa · 15h ago
Structured data for AI agents

Repository: sveltejs/svelte. Description: web development for the rest of us Stars: 87951, Forks: 5197. Primary language: JavaScript. Languages: JavaScript (71%), Svelte (22.3%), TypeScript (4.8%), CSS (1.1%), HTML (0.8%). License: MIT. Homepage: https://svelte.dev Topics: compiler, template, ui. Latest release: svelte@5.56.9 (2d ago). Open PRs: 100, open issues: 1023. Last activity: 10h ago. Community health: 87%. Top contributors: Rich-Harris, Conduitry, dummdidumm, github-actions[bot], trueadm, tanhauhau, paoloricciuti, benmccann, PuruVJ, baseballyama and others.

·@ofershap

Replace github.com with gitshow.dev