W3C

– DRAFT –
declarative partial updates

12 November 2025

Attendees

Present
dmurph, frehner, JakeA, jcayzac, kbabbitt, kizu, LeoLee, masonf, matatk, oriol, sisidovski, Thomas_Steiner, wendyreid, ydaniv, zcorpan
Regrets
-
Chair
Noam Rosenthal
Scribe
mmocny

Meeting minutes

NoamR: Discussing Declarative Partial Updates
… we can bikeshed the name.
… collection of a few different things with a common name
… common purpose
… but they work on their own without the rest
… individually useful, but work nicely when combined
… I will go over all of it in breadth first, shallow, then in depth with questions from the room
… (joke about photo)
… this is about the navigation experience on the web
… make it feel like moving between pages or states, whatever that means, make sure it is fast and smooth and customizable
… i.e. brand, creativity
… fast and smooth sometimes are at odds with each other
… in the last year, most of the features are "defer" or "later" all these things... render blocking... everything later, but want things to be fast... and smooth
… animations are smooth but by definition slower than instant
… third part is customizability for authors
… a design principle for this: declarative is key
… that word can be overloaded with many meanings. Ours is: less event-driven javascript that you have to use in real time
… declarative doesn't mean no JS, it might be useful to use script to define a set of rules-- but shouldnt be needed in real time
… declarative by that definition-- we have less jank, less bundle size, less lifecycle errors (than script), ... and more opportunties for browser optimizations
… We have 3 meta-features:
… Updating the DOM
… there are low level primitives right now, one fragment at a time, or stream into the main document response
… but when you start wanting to update the document, you cannot stream... now you have to write scripts in real time for every change in the DOM... this is the role of frameworks much of the time... respond to event and make updates to dom
… two solutions : out-of-order streaming , and stream to element
… 2: Gestures
… Right now supported gestures are scrolling and clicking (this is a gesture), most interfaces are just this-- but native counterparts have a lot more gestures, more swiping (dismiss, refresh, etc)

<masonf> swipe left, swipe right

<tomayac> RRSAgent draft minutes

NoamR: today uou have to use libraries that deal with tyouch events, and this is difficult
… need to use position sticky and multuiple scroller elements
… with native gestures, you perform actions, like swipe to dismiss
… (snap-to-activate)
… another value of declarative is (main thread congestion)
… I come to this from web perforamnce, and there is a lot of congestion on the main thread, and a lot of the value of this work is to be able to delegate, content templating to a worker or server
… and gestures to a compositor, and things browsers can parallelize, without having to make js threads
… Stream to element: being able to drive UI updates from server or worker
… From a server it is very common from frameworks, like React, renderToStream. Takes a react tree that isn't ready and puts in placeholders. Same is marko. Others that dont have this have open issues for it (like Nuxt)
… Other UIs are very dynamic, i.e. chat-style
… these are served as-they-come and can be out of order
… (showcase code example)
… Stream html to shadow root, unsafe version is to trust the source, then example of how to use it (piping)
… From that moment on, the html goes from response to element
… You can do whatever you want in that stream, no oppinions
… Out of Order streaming
… (another example): serving content when it is ready
… example, select box with a list of countries. Often start with loading... and then you fill the list with a slow library to get a list
… (example shows template element that will replace children)
… Will replace things in the order they become ready from server
… Overscroll Gestures: reveal/conceal elements
… examples from bluesky. Today they have this in native and not in the PWA, because it was hard. And sad.
… (Example, but this one is less advanced in terms of spec discussions, so this is WIP)
… Example drawer-menu and overscroll area
… so the menu is a think on top of the container
… Will discuss more in the CSS WG on Friday morning
… Snap to Activate: gestures as progressive enhancements from clicking
… often you would have a button that does the same things
… accessibility guidelines say to have a button, but gestures enhance the experience
… when you scroll snap to a place, you will actually click something
… initial ARIA conversations: if we do it right, could also connect this to screen readers.. i.e. if you scroll left/up you will show menu or reload... so you finally get semantics vs what you have today with manual handlers and actions
… also: predictive things, since we know where you are going or might go, we can predictively load new content for example, or reveal a tab in a list of tabs, start streams
… this is not designed at all, but it is a progressive enhancement
… create a relationship between items, snap --> click

CSS Route Matching: style based on document URL
… apologies this is so broad-- partially this is just to give you FYI so you can followup in the repo
… This is about styling the navigation experience. A year ago we released cross-document view transitions, declaratively between pages
… but we found that in order to make it custmizable you really need to know where you are coming from AND going to
… in order to do this, currently you need to intercept the events on both sides, the url you are coming from and to and make custom decisions -- not very declarative
… recently on bluesky someone said that using cross document VTs is like flying without a direction
… it is too hard... we will talk more about this on Friday
… (example of css route matching) where from / at / to
… e.g. going from movie list to movie details, it will... expand-thumb-to-hero
… lets you Express this where it belongs.
… preview before commit: And allowing you to customize this with script.
… lets you show an exit thing
… This is not declarative but it is customizable
… if we are not ready to render yet, will show a same-document navigation of a preview, and then switch to cross document
… or we could make it declarative if a navigation prefers...
… we are done! lets get to the queue

JakeA: if you create two writeables at the same time, will they be racy?

Noam: Yes! we thought about it then said lets try it its easier

JakeA: Q about example

NoamR: it was wrong...

JakeR: innerHTML question

NoamR: by default it would not expand template, because that would interfere with existing sanitizers, but when you stream append for example with patches, then it would apply

JakeR: in the scope of entire document?

NoamR: No wherever it applies to, parent of the template

shared anscestor?

JakeR: will this encourage updates anywhere in document, get writable for the whole body?

Philip: might have a mode that only does append, but dont have that...

NoamR: They dont interfere with each other because they have a separate parser, but appending to dom could interleave ...

JakeR: (asking about the example, nuanced question)

jcayzac: <is there a declarative way to use streamHTMLUnsafe>

NoamR: Yes eventually, but this is first step, HTMX was inspiration, but we want to be careful about not being oppinionated. HTMX can be oppinionated-- and that is okay for a framework

<masonf> (or at least that's what I heard)

NoamR: if there will become value to layer oppinions on top of primitives we can evaluate, but want to start with less script/events needed first

dmurph: this is cool, I like it. We spent time on the previous page, document to navigate, scoped to PWAs...

dmurph: link capturing, navigation capturing now, destination can declare and intercept, handle in a more interesting way

dmurph: right now the most advanced thing is focus my tab-- but now we could do navigate api... im interested in this!

NoamR: Is this just navigation api?

dmurph: its more, i.e. clicking a link to a calendar to figma, and normally open window, but now you can switch to window in document

dmurph: (asking about example of worker/sw)

NoamR: I would summarize all of this as integrating this proposal/parts with the navigation api

NoamR: Lets chat later!

kbabbitt: I also love it

kbabbitt: Wondering about making more declaraitve-- reminds me of svg filter declaration, and building skeleton and then piping to text decoder and pipe to element

NoamR: Discussions about templating, dom parts, things going on in parallel-- but felt like we should go one step at a time-- lets enable a primitive for streaming first

NoamR: No need for detached document streaming that has lots of constraints. Once the dust settles we can return to it next.

<Zakim> zcorpan, you wanted to say auto-clicking on scroll snap defined in css could be sec-sensitive

zcorpan: Scroll-snap-to-activate idea, seems like a new idea added to css, trusted clicks might be security sensitive

zcorpan: today might allow untrusted css, which might allow css-providers to cause trusted clicks that aren't expected

NoamR: it sort of can already do that by putting UI on top of buttons... css can already make you do things (by convincing details)

NoamR: the other part of this is, its just a proposal for now

zcorpan: just noting

??: Related to that scrolling doesn't count as transient user activation and now it will trigger this based on what the user would previously consider a scroll

wendyreid: soudns really cool. Some more to consider: interaction with the screen reader and concerns about dynamic content and not updating accessibility tree quickly (its janky often today already).

wendyreid: overscroll concerns, single pointer gesture... cannot rely on swiping as the only way to do things

wendyreid: how would we commicate that to screen readers and other AT's

wendyreid: the idea of more gestures to the web presents some opprortunity for "reduces gestures" akin to reduced motion?

wendyreid: ...there is a lot. But its really cool.

Bas: what do Native apis do for this?

wendyreid: their are some control for not accepting or reducing gestures, and when you use AT's the gestures are taken out automatically.

Bas: is the content author responsible?

wendyreid: you need to not override default screenreader gestures

lea: Q about writablestream-- will you be streaming HTML (yes) -- what about streaming data like JSON, can you write a transform stream?

JakeR: Yes, you can write your own transform stream

NoamR: and you can do that in a worker

NoamR: you can do fancy things like GraphQL

(??) stream of html that gets turned into elements

JakeA: ... question aboiut run-scripts option?

JakeA: I've been hoping to make this behave like regular html parser, ie html includes

Philip: as close to fragment parser not main parser
… it will be like setting innerHTML

NoamR: will act as a regular fragment or contextual fragment that does run scripts

JakeA: I would like to go further than that...

Philip: Want to add additional controls to add one by one, but by default act like innerHTML

Because it is streaming running script end to end would be consistent-- thats what jake wants

wanderview: abort controller integration?

Philip: There is no promise, but you can abort a stream

JakeA: maybe a similar Q-- what happens when the stream errors?

NoamR: it just stops what it was doing, and everyone gets an error

(reference to abort the parser spec, ...)

wanderview: does anything happen when the pipe completes

wanderview: is there an event?

NoamR: possible we could have an event, or for errors i.e. fail to match to content

wanderview: this might make things more tightly coupled-- what creates content and the ... reference to 'load' events

NoamR: deliberately didn't want to do that-- but you can generate your own events

We could fire these events onto document, because no event target, but haven't throuhg it through

camille: Q about streaming html and trusted types

Philip: we discussed this, but cannot make streaming compat with trusted types, because of chunks

camille: I get that but...

Philip: For now, if you have trusted types, streaming simply wont work-- but we want to update the sanitizer spec for streaming

camille: Reference to the options for safe/unsafe

NoamR: For the user case ... pass an options dictionary ... (this is complicated)

JakeA: we spoke about this on github a while ago
… example with html and templates
… If I have one of these for each of my pages
… but one of the pages has a custom sidebar-- does every single page now need this sidebar

NoamR: we discussed about iframes and reloading each time..

JakeA: Yes, several problems, but I'm referring to all the includes needing to have Everything that anything has

JakeA: But also the react-esque question about replacing elements vs persistance

NoamR: yes, but its no worse that separate html files
… for the second we dont solve yet, but idea is "content-revision" attribution, super crude virtual dom... dont patch if you think it is the same

frehner: for out of order streaming, would this only work for initial stream / initial load?

NoamR: you can combine the two together

frehner: what about SPA with 100's of routes and long lived, is there concern about having many of these stay forever

NoamR: they dont stay

Philip: we don't attach the template, just the final dom

JakeA: declarative shadow dom is the same

NoamR: we were thinking about template conceptually as a scripting directive, but its a declarative update
… regular template is a deferred update, and declarative shadow dom is an update to the root-- but this is...

jridgewell: why is this incompat with trusted types? couldn't we have create html chunk?
… trusted types give you sanitization but also ... but if we had createHTMLChunk it could work for this specifically

Philip: this was one of our first attempts for this
… trusted html chunk was the first prototype
… (tldr you would still have to implement your own parser and cannot use browser parser)

Simon: yes, but you could still stream into inert and then parse that
… but the browser streams first, then other script can look at that stream after

Philip: ...it would only work if you have a bunch of sibling nodes, not a giant root

Simon... because you need to sanitize the tree not the string?

NoamR: main solution is to have trusted options things, but we dont want to ship that before working on the sanitizer
… once that ships you won't need to use the sanitizer and could use trusted types

noam: (NoamH): could this be used to implement a infinite virtual scroller? But such a component would also require to remove elements as well as append

Philip: 4 modes append, prepend, replace, ?

NoamR: we will likely need more content methods in the future, this was just a start
… nothing prevents us from having more, this is a start

Simon: you want to append on one end and remove on another

westbrook: contentname right not only addresses a single element
… but if you could do multiple, could it be a way to do declarative shadow dom replacement?

NoamR: like a comma/space separated list

Minutes manually created (not a transcript), formatted by scribe.perl version 248 (Mon Oct 27 20:04:16 2025 UTC).

Diagnostics

Succeeded: s/missed the q/is there a declarative way to use streamHTMLUnsafe

Succeeded: s/(?) svg/svg filter declaration/

Succeeded: s/override defaults (?)/override default screenreader gestures/

Succeeded: s/stream/string/

Maybe present: ??, Bas, camille, JakeR, jridgewell, lea, Noam, NoamR, Philip, Simon, wanderview, westbrook

All speakers: ??, Bas, camille, dmurph, frehner, JakeA, JakeR, jcayzac, jridgewell, kbabbitt, lea, Noam, NoamR, Philip, Simon, wanderview, wendyreid, westbrook, zcorpan

Active on IRC: breakout-bot, camille, dmurph, emilio, frehner, JakeA, jcayzac, jridgewell, kbabbitt, kizu, lea, LeoLee, masonf, matatk, mmocny, noamh, oriol, sisidovski, tomayac, wanderview, wendyreid, westbrook, ydaniv, zcorpan