WDDS25, the Big Stonking Post™
Web Directions Dev Summit 2025 was held on November 19th and 20th, at the Dr Chau Chak Wing building at UTS in Sydney.
- Themes
- Trends
- Disclaimer & Image Credits
- The talks
- Jono Alderson - The Browser Strikes Back: Rethinking the Modern Dev Stack
- Juntao Qiu - The Evolution of Frontend System Design
- Lovee Jain - BFFs could be your new Best Friends Forever
- Zach Jensz - Offline AI Web Apps
- Geshan Manandhar - Embrace feature flags, unlock better customer experience and developer confidence
- Ryan Yu - Understanding Recursion for Elegant Solutions
- Tim Nguyen - Form control styling
- Lee Meyer - Supercharged scrolling with CSS
- Dmitry Baranovskiy - Let No One Ignorant of Geometry Enter
- Rupert Manfredi - What’s beyond the browser: the AI platform shift
- Kevin Yank - How to Build an Agent in JavaScript
- Anna McPhee - Teaching Your Frontend Tools to Talk to AI
- Tamas Piros - When AI Stops Talking and Starts Doing
- Mandy Michael - Developing a Shared Language for Designers and Engineers
- Eiji Kitamura - State of identity and authentication on the web
- Beau Vass - A false sense of accessibility: What automated testing tools are missing.
- Tammie Lister - From Components to Prompts: Rethinking Design Systems in the Open
- Katja Forbes - Your Code is the Customer Experience
Themes
In the hallway track, there were many discussions about floors and ceilings. The skill floor being the minimum level required to perform to an adequate standard; and the skill ceiling being the maximum possible level of mastery. The general analogy can be applied at multiple levels - from an individual’s progress, to the peak of possible performance.
A sporting example is to compare the skill levels required to join a local football team, versus an elite first grade team. The concept can be applied to frameworks and tools like LLMs - are they lifting the floor or ceiling?
John also mused that the web is in a stagnant period, with React being so entrenched it feels like a local maximum may have been reached. While I understand John’s sense of ennui, we have seen these periods before. jQuery wasn’t the web’s ceiling, and I don’t think React is either. A new era will happen, it’s only a matter of when and what it turns out to be.
Trends
- Hybrid attendance - Dev Summit had roughly 50/50 in-person and online attendance; and all questions for speakers were taken from the live chat.
- The phase out of Twitter handles was almost 100% this time; but what was interesting is more people are showing their own site or blog URL rather than a social media link. IndieWeb represent!
- …however there was also a surprising surge in LinkedIn links. Whether you consider that a ‘social network’ or not is an exercise for the reader.
Disclaimer & Image Credits
- These notes paraphrase what speakers were saying. If you need an exact quote, use a definitive source such as a recording or slide deck.
- FWIW these are my own notes taken during the event, not an AI summary.
- Most photos are from Kevin Yank’s Dev Summit 2025 gallery - used with permission, thanks Kevin!
- Slides aren’t credited (context should be clear).
The talks
Jono Alderson - The Browser Strikes Back: Rethinking the Modern Dev Stack
Jono acknowledges a similar feeling to John, where there is some pessimism about the state of the web - that is, that so many of the sites we use are simply crap.
As an SEO consultant he looks a lot at how to make it easier for non-human users - SEO bots, which we’ve had for most of the web’s life - to use and understand websites. He looks at everything from small local business website, all the way up to massive multinationals.
He sees slow, over-engineered, complex sites that are haemorraging opportunities… unnecessarily! Did we just not learn to have the hard conversations about how to build things?
The web is stuck in the past.
Not so long ago, “magic” was still the post - you’d order a movie, and days later a DVD would arrive in the post. This was a thing in 2002 with LoveFilm - long before Netflix. In 2007 Netflix revolutionised the process of shipping DVDs, and nobody complained about waiting for the film to arrive. In this era, the web was still slow as well - people expected to wait while things downloaded. Latency was part of the charm of the early web.
Netflix posting DVDs worked because the web was still too slow, and they were working around that limitation. We are still doing that on the web - shipping huge chunks of code to work around limitations.
But those limitations aren’t there any more! Why are we still doing it? We don’t need massive polyfills and libraries. We missed the bit where the infrastructure got fast and the platform became powerful.
The web is still posting DVDs. We just keep making more sophisticated envelopes and tracking services. They are clever, but they are logistics, and potentially unnecessary.
What if we could get all the value we want, without having to ship runtimes? We have doubled down on patterns that don’t deliver value to users. React creates its own DOM… it is recreating the browser inside the browser… it’s like renting a car and pushing it everywhere you want to go!
We have an endless committee meeting about how to recreate the browser inside the browser, then we wonder why it’s slow. We built beautiful machines for a broken world. The world we built for doesn’t exist any more.
We now have metaframeworks to manage our frameworks to solve problems of our own creation. It’s brilliant but exhausting.
It’s like stacking DVD players on top of each other and wondering why the picture doesn’t get better.
What if we stopped fighting the browser and started using it? Browsers are really good at fetching and rendering content. The native web is resilient in ways SPAs aren’t.
We created monsters. The web is objectively bad today. We’ve normalised the process being difficult for developers and the result bad for users.
But the reason for optimism is that the browser has caught up! But we haven’t looked up long enough to see all these capabilities coming in.
Jono proposes an idea: when Angular originally took off, we stopped talking about websites and we started talking about apps. And those are different things! But in the business world decided apps were shiny and websites were broken, and started demanding apps.
Most of the things of the web, when you look at the full breadth of it, are not apps. They do not have the complex interaction requirements of an app.
…
We no longer have to fake things. We don’t need so many layers any more!
Things we should be playing with:
- Popover API - this can handle any interaction where you need things to take focus and close again without focus
- Forms - forms are awesome now! They are powerful and styleable! We
can use native validation and
:has(:invalid)to show form state on the fly… without any JavaScript! - pure CSS carousels (You still shouldn’t use carousels. - ed)
- Smart image loading with
picture- get rid of all those JavaScript image handlers - predict navigation with
speculationrulesandprefetch/prerender…assuming your site is already fast and you aren’t just DDoSing your own site with requests it can’t process fast enough - Native caching with
Cache-Control- none of the major frameworks do this well localStorage- Compile hints -
//# allFunctionsCalledOnLoad hidden="until-found"- inherently accessible display:none- Content visibility - lazy loading for everything!
- Containment
will-changeIntersectionObserverto watch the DOM to see when an element is visible- Back/forward cache (bfcache)
- View transitions - possibly the most exciting thing to happen to the web in years. This can make anything feel fast and smooth, without needing an SPA… or in fact without any javascript! This kills almost every argument to use SPAs for websites.
All of this works together, and works without massive build chains.
…and yes you can do all this with React, but nobody does because they’ve all stopped looking at the actual output. And also because React often takes years to support things the web already does, and it’s still janky AF because it has to fit into their reinvention of the browser.
We need to render on the server, not the client. Pushing everything into the client undoes a great deal of the web’s optimisations.
You don’t have to reject frameworks, and they are not evil. Frameworks need to get smarter and smaller. Let the browser handle more things, and have the framework focus on the business logic. Small is the new fast.
Semantic HTML is cool again - not just for humans but all the bots and agents trying to make sense of your site. Structure also equals accessibility - and you need your site to be accessible!
Look at the output again. Don’t just stare at the abstractions.
Resource: web.dev/baseline
There are still some things missing - frameworks are likely to stick around handling complex state and persistence for a while yet.
Native wins. The web just works. Join the rebellion!
Juntao Qiu - The Evolution of Frontend System Design
Juntao starts by asking us if we’ve ever estimated a frontend task to be small (couple of hours), and it turned out to be huge (couple days). Yes, nearly all hands went up and a few people were lying.
Running through an example of building a user picker component…
The number of states you need to track does grow quickly in a modern app. Not just the visible states but all the server and transfer states along the way… and if you are unlucky you get a ticket raised where opening a user picker freezes the entire app (because so much data is being fetched behind the scenes, the UI stops). So then you add data pagination and you have to track that… and you’ve changed the contract between the frontend and backend.
But then you get a user request to add search so you don’t have to scroll through it all… and there’s more to handle. You end up with lots of state to manage and code that’s complex to maintain.
Then you get a QA ticket that you need to add keyboard controls, so you need to add on more listeners…
Then you get a translation ticket because German translations overflow the dropdown…
It all gets very complex to handle what looks like a simple interaction. Multiply this by every component you have in a complex app - in this case it’s Jira - and you have megabytes of JavaScript being downloaded and executed.
To add to all this, different components may be maintained by entirely separate teams; fragmenting effort and ownership. If something breaks, responsibility isn’t always clear.
So going back to the original question - why do simple UI component tasks turn out to be complex? The component is the tip of an iceberg. The component lives in a complex ecosystem with multiple systems intersecting in the browser.
Take aways:
- design for complexity - it’s inevitable in current apps
- think in systems - components aren’t isolated, they’re part of a system
- design for failure, not just the happy path
- build your personal mental model of the system you are working in - you don’t have to know everything, but you need to understand how it fits together and how things flow through it
Lovee Jain - BFFs could be your new Best Friends Forever
(BFFs = Backends For Frontends)
Lovee starts with a Star Wars scroller - Architecture Wars: THE RISE of BFFS - the gist is that BFFs were a result of teams trying to move from monoliths to microservices. BFFs add a middleware layer between APIs and frontends, to handle situations where the APIs are too generic to serve all needs; or a system is part way through a migration and needs to assemble data from multiple sources.
A typical example is a BFF creating a light response for mobile devices, to avoid doing assembly and manipulation in the client. This is good for APIs that serve all the content required for multiple solutions - the BFF cuts the response down to just what one specific solution requires. You could also create more APIs, but not all teams work this way.
Another example is needing to provide alternative APIs, eg. to sell a B2B API without a UI at all, from a common backend. The “frontend” in some cases doesn’t exist, but the common middleware layer is the same and gets rolled up with BFFs.
BFFs should not have any business logic; and they will often be maintained by the frontend team so the BFF can be changed to suit the UI. They also to create options to handle API changes, and can serve as a caching layer.
Caveat: YMMV! BFFs aren’t going to benefit all teams and systems. They do inherently add latency - another layer cannot exist without adding some amount of latency - and it has to be worth that. You are likely to get some level of code duplication across BFFs; and the decoupling may not have a big enough ROI.
BFFs do play well for organisations where separate teams maintain each service/microservice/microfrontend… or when one team needs to manage a specific ‘slice’ (eg. both the micro frontend and the BFF that serves it).
As with most architectures, a key question is how many BFFs you actually need. Just as you could have too many (or too few) microservices, you can have too many (or too few) BFFs.
Why choose a BFF?
- specialised frontend needs
- performance
- team autonomy
- security and privacy
Why not choose a BFF?
- complexity
- infra and maintenance cost
- high overhead for small projects
- API synchronisation
What if BFFs are actually your enemy? Potentially you might try GraphQL, adding more APIs/microservices, etc. You don’t have to adopt BFFs!
But if you are migrating from monolith to microservices, you might find BFFs help that transition and buy you some time for that work.
Are you ready to befriend a BFF?
Zach Jensz - Offline AI Web Apps
There are times we want to view content offline - the most blunt version is to download a PDF to your device.
But we have other control methods like Cache-Control
that can paper over spotty connections - if you’re offline you see the
cached version, and you can reopen pages out of your browser history.
But it’s not deeply reliable, there are a lot of ways you can lose that
cache or it just doesn’t work.
We’re on spotty connections reasonably often - tunnels, planes, going camping… we should design for it.
You can choose to store things using service workers. This lets you cache things like fetch requests. You can then make this completely save-able by adding an app manifest, which makes websites look and feel like native apps.
How do you update these caches? You can use
navigator.online to check if a connection is available,
then go fetch a new resource and only go to cache if that fails… but
it’s not entirely reliable. true means “no not-internet”.
You can run into “Lie-Fi”, where there is a connection… but not really.
It’s an online-first approach. An offline first approach is to
default to loading from the cache.
Resource: Workbox
You can use things like IndexedDB to have a local db; and background sync for updates.
Use navigator.storage to keep track of how much you’re
storing. Chrome doesn’t warn you but it will happily use terabytes if
they’re available.
There are some preloading ethics - consider transfer costs paid by the user, environmental impacts of unnecessary prefetching, plus security and privacy implications for storing lots of extra data.
Browser support is mostly good, but it can’t be ignored that Safari on iOS is lagging behind; although there are complaints that Chrome may be rushing forwards. There are a lot of issues (practical, legal, ethical…) around the competition between native apps and progressive web apps.
…but wasn’t AI in the title of this talk? There are offline AI options:
- Gemini Nano for Chrome but beware this is hungry - it wants 22gb of device storage, 4GB of VRAM or 16GB of RAM, and an unmetered connection. (Oh is that all? -ed).
- WebLLM
- WebGPU
- Web Neural Network API
- ML API - a long way from production, you’ll need to flag it on
We are close to having offline AI to do things like summaries, object detection, image styling, etc.
So why aren’t we building PWAs?
Open Web Advocacy is a group educating legislators and pushing for a more open web.
Geshan Manandhar - Embrace feature flags, unlock better customer experience and developer confidence
Have no fear of perfection - you’ll never reach it. - Salvador DalĂ
Feature flags are a way to decouple shipping code from enabling features. You can think of permissions as long-lived feature flags - whether you paid to access a feature is a toggle… a flag. But it’s commonly used as a term for releasing new features, or new versions of features, “behind flags”.
Some flags are short-lived, others long-lived, it depends a lot on what you need to do.
Feature flags enable tranched releases - rolling out to a small group of users first, then going to more once you know the feature is ok. (If only crowdstrike had done this!) They also enable quick rollback if a problem does appear.
How to use feature flags?
- start small - literal
ifstatements in your own code will work - later you will probably adopt a flag management option like LaunchDarkly. There are also open source options - don’t roll your own, regardless.
- focus on the feature flag mindset, not just the tooling
The mindset of feature flags is important. It gives you options on how to manage risk, who can manage feature launches, and so on. Code can be release well before a desired release date, and toggled on when the launch is ready (eg. to coordinate with marketing).
Best practices:
- limit the scope of each flag / keep it simple
- clean up old flags and the code that calls them
- set up proper access control and have audit logs
- follow a clear naming convention; add tags if possible - eg. for who owns each flag
Benefits:
- better customer experience - more testing options means you avoid using production users as testers
- higher developer confidence - avoids long-running branches, test in production environment before release, and easy rollback when things do go bad (42% of LaunchDarkly customers recover from erros within an hour)
It’s not a free lunch:
- they do add complexity, and can make testing harder
- misconfigured flags are a whole new bug/incident type
- rollback is complex if a feature is not read-only (ie. if data has already been written)
Top take-aways:
- use feature flags only when it makes sense
- follow best practices (particularly cleaning up old flags!)
- flags enable better customer experience (dev confidence is a bonus)
Geshan’s slides | geshan.com.np
Ryan Yu - Understanding Recursion for Elegant Solutions
Recursion is a common CS term, but remains a little mysterious despite being common.
Starting with the basics… what is recursion? Three elements:
- a function that calls itself
- …with a base case that ends recursion
- …and a recursive case that resumes recursion
When they are not set correctly, you get infinite loops and stack overflows… which is probably why people find these scary.
function sumRange(num) {
if (num === 1) return 1;
return num + sumRange(num -1)
}
sumRange(5) // returns 15
Ryan ran through a visualisation of how this works.
Classic errors leading to infinite loops -
- never meeting the base case
- not sending different input in the recursive case
Since we could also write an iterative solution, why use recursion?
- clarity and readability - in some cases, recursion will be easier to read and understand
- for unknown depth/branching
To put it another way the time and space complexity may be lower with a recursive solution (his examples of recursion had Time complexity O(n) and Space complexity O(log(n)).
…
Calculating node depth - example of a binary tree, and calculating
node depth with depth-first search and PostOrder base case is a node
with left and right children that are both null
Backtracking - example finding all the possible subsets of an array.
Input = [1,2,3]
Output = [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Note - this was a technical deep dive that does need the visual aspect to aid understanding; if you are interested you are better off checking out Ryan’s videos than having me try to write it down.
Tim Nguyen - Form control styling
Tim notes that there is a story behind all code - whatever you see is there for some reason. So, why would websites use buttons to recreate checkboxes? It was probably difficulty with styling them.
Form inputs go into “primitive appearance”; but for checkbox, radio
and range you need to set appearance:none which removes
everything and you have to rebuild them from scratch. It’s
error prone and easy to miss things - the user agent styles apply a
lot of things.
So why do browsers insist on primitive or native appearance? If you go back in time to the early days of the web, best practice was for browsers to emulate the operating system; and to render things as consistently as possible.
In the 2010s CSS got more powerful, and brands started to care more about how they were presented on the web. So people got annoyed with default form inputs and replacing them with custom components. Now the web standards are opening up to be more flexible.
Spec: CSS Form Control Styling Level 1 (Tim is the editor of this spec)
New property appearance: base gives a more useful option
than appearance: none - it inherits the base style of the
page.
Some principles applied to base controls:
- controls look the same in all browsers
- controls are recognisable and usable without additional styles
- controls pass 100% of WCAG 2.2 AA standards
- styles are consistent across controls in look and feel, and in how they are defined in code
- the styles are easily adapted to the website’s branding, without needing complex resets
Neat features:
field-sizing: content- good for sizing textareaswriting-mode: vertical-lr- form controls used to be forced into horizontal- standardised pseudo elements -
::field-text,::step-up,::step-down,::step-control(container around the up and down steps)
Tim ran through some examples of styling form inputs in the future
state when the spec is mainstream… a key thing to note is many cases use
content to replace form controls rather than
background, :before etc. Because the defaults
are smart and the selectors clear, you don’t need much code at all.
Some neat callouts - sliders will expose their current value using
content: control-value(). You can add that to an
::after and then use CSS Anchor Positioning to have it
float over the slider thumb. You will also be able to use control-value
within calc (exact syntax to be decided).
This spec is nearly at prototype stage; which means you can still have real input into the design process.
Lee Meyer - Supercharged scrolling with CSS
Scroll-based designs have become very popular, including some incredibly effective use of scroll-driven design in journalism (not just neat marketing sites).
Example: a cube that rotates as you scroll, on a page where the
background colour gets darker as you scroll. The JS version has a ton of
code, or you could write… animation-timeline: scroll()
(browser support is just waiting for Firefox before it goes
mainstream).
Example: view-timeline used to rotate an Xwing model
scroll-trigger-animations adds some persistence - you
can add things while scrolling, and have them persist rather than fading
back out if you scroll back. Example: Pong in CSS! It tracks the loss of
player lives, moves the paddles up and down, and tracks the game state
to completion.
To really push this idea, Lee created a demo of a playable scrollytelling game! Includes parallax scrolling, multi-direction gameplay, inventory, collision detection and endgame cut screens.
Design is storytelling - if that fits your use case, it’s built into the platform!
This was a very visual session, so check out the demos and code at codepen.io/leemeyer
Lee’s slides | Lee’s articles on CSS tricks
Dmitry Baranovskiy - Let No One Ignorant of Geometry Enter
“Let No One Ignorant of Geometry Enter” is a reference to Greek history… supposedly it was written above the door of Plato’s academy, basically saying “if you suck get out”… but Dmitry will be kinder than that ;) The point is that an understanding of geometry, or maths in general, was considered a necessary foundation for philosophical thinking.
Dmitry once needed to set margins for a printed page, and thought… well he’s a developer not a designer, he looked for a formula. He didn’t read to the end of the article and did a bunch of calculations, only to find out the measurement is “one ninth of the page”. The original approach of drawing lines across the page suited people doing this with a ruler. But that doesn’t help code.
Proportions - a square is 1:1. Drop the diagonal, and you get a rectangle. Keep doing this and you get the golden ratio, and that’s how we got paper sizes (A0, A1, etc).
Slide: a clay fragment from 1700BC shows how to calculate the square root of 2 in base60, which we still use for time and angles - a legacy of Babylonian maths.
Another interesting clay fragment from the age shows Pythagoras’ theory.
So why care about the square root of 2? It’s very useful for
fractions, even if we don’t know the exact number. We’re lucky in JS, we
have Math.SQRT2 and don’t need clay tablets. Square root of
3 is also useful, our screen resolutions map very closely to it.
Golden ratio - phi. You see this ratio in the Fibbonacci sequence, which we all know from interview questions.
Geometry is taken very seriously, by some people, particularly in art and architecture where the golden proportion comes up regularly.
Spirals - honestly you need to watch the video, describing spirals is hard ;) But not all spirals are the same, and not all of them have the same ratios, and not all of them have the same effect when rotated. Some will hyponotise a Web Directions crowd into loving Dmitry’s talk.
Bezier curve - actually invented by three people, not just Pierre Bezier. They are a linear interpretation between two points, used to draw a line. They aren’t really what people imagine them to be, which is why they’re so hard to draw in Illustrator. We also use bezier curves in SVG and CSS.
Youtube: The Beauty of Bezier Curves
Transformations - x, y, w … “w for WTF”. A lot of CSS calculations (scale, rotate, translate…) translate to mathematical matrix calculations. Most of the time the right column is 0 0 1 so the APIs just assume it’s always 0 0 1.
The ultimate point here is that hopefully this has opened, or reopened the door to maths and geometry. It’s full of interesting stories and fun techniques - it’s way more fun to come back to maths than it was when you were forced to do it in high school!
Rupert Manfredi - What’s beyond the browser: the AI platform shift
Since the dawn of computing the atomic unit of computation has been a bit - 0/1. We arrange bits into logic flows to scale up into general purpose computers. The first general purpose computer, the ENIAC, was programmed with patch cables. We moved on to punch cards, to CLIs and eventually to apps in GUIs.
Expert application developers would handle the deeper understanding of all this, so the average user didn’t need to. But even so many people still struggle with computers and software.
Three key problems:
- Volume: there’s too much stuff
- Complexity: there are too many apps
- Misalignment: I’m not in charge (the user does not feel in control)
If computers are the bicycles of the mind, shouldn’t they be lighter and more customisable? Some software feels more like an aircraft carrier - vast, confusing, and out of our control.
At the heart of it all is the need to make everything into instructions that can be solved with binary units. The instructions have to be known well ahead of time for the software to respond.
Neural networks change this fundamental basis. They are nondeterministic and multidimensional; and can respond to much more fluid instructions - like LLM prompts.
But it takes time for things to evolve - cars didn’t arrive immediately at what we currently recognise as a car, they went through iterations from being a faster horse to modern cars with dedicated infrastructure to enable them.
Most LLMs are still at the faster horse stage - trying to work like a familiar application, or integrate with them. It’s unlikely to be the final iteration.
Demo: Telepath - voice based interaction with personalised historical context (including personal and work), and access to search the web for new information. The UI responds dynamically to each task; and uses context to anticipate user needs.
Why Rupert thinks this will happen…? being careful to note some things about it will be wrong, it’s going to change over time… platform shifts are predictable and normal. We already have the core technology that’s doing lots of useful tasks, and it’s rapidly improving with current investment.
But there’s no browser. What does this mean for the web? The web is currently a platform for applications and information.
Telepath doesn’t work as a monolithic app, it uses composable parts. But its role is still to be a user agent - a program that accesses and mediates the web for the user. Plus there is a lot of promise for local AI agents to bring things onto our own devices, which will lessen many of the big objections to current-generation AI.
Also information on the web is terrible! Optimising for attention has created low quality content. AI slop is making this worse - some estimates say up to 50% of new articles are AI generated. Meanwhile revenue for publication has plummeted, making it a non-viable business model for many.
So what do do? We’ve talked about centralised subscriptions and micropayments for the web for decades now - 402 ‘payment required’ was in the original HTTP specification. We’ve had visions of the semantic web - a web readable by both humans and machines. The web in some ways anticipated what we’re seeing now.
What does this mean for web developers? Our job was never to write software, our job is to solve problems for users using software. The solutions will change but the jobs don’t change as much as we might imagine.
We need to keep the mission alive. The web was never intended for walled gardens and centralised control, and the web has survived multiple rounds of the open vs close battle.
While we are facing a period of great change, there is still plenty to be excited about.
The web is dead. Long live the web.
Kevin Yank - How to Build an Agent in JavaScript
Kevin credits Thorsten Ball from Sourcegraph, as Kevin used his blog post as the foundational model for this talk… which seems very appropriate in the world of AI.
Coding agents are exploding. Google launched a new one, Antigravity, just last night.
Like most devs, Kevin doesn’t really trust new tools without a strong mental model of how they actually work. So to do that, let’s make our own coding agent… but the blog post uses Go (golang). He didn’t really want to learn Go for this, so he decided to translate the idea into JavaScript. So today he’s speed-running the post making an agent in Typescript for NodeJS.
The pieces are relatively straightforward - you get an SDK, and out of the box you get a stateless chat. To create session state (so it ‘remembers’ things you’ve said in the chat), the entire conversation is logged and the whole sequence is sent to the API with every call. You suddenly have a viable chat bot with a surprisingly small amount of code.
From there you can add ‘tools’ to process particular kinds of task. The analogy is to say “in the following conversation, wink if you want me to raise my arm” - you’ve given the agent a specific capability it would not otherwise have (your conversation partner now has a sort of power to raise your arm). The demo for this is giving a short piece of weather data, and getting a generalised ‘weather report’ as a result.
Bigger demo: a read_file tool. Noting it’s all “wink if
you want…” stuff that results in strings being sent to the model. The
core of it is a nodejs file that reads a file path and returns the
contents as a string, that can be used as part of the chat.
However! Kevin was obviously not happy to have given Anthropic uncontrolled access to any file on his computer. So he added human in the loop, where the tool has to ask for permission before reading a file.
The process goes on creating a small set of tools sufficient to read and write files, and now you have built a functional coding agent. It really isn’t magic, you’re just calling an agent via an SDK; and choosing whether to give the application access to your system.
So where is the “agent” here? Kevin argues that it’s the whole picture, including cloud AI services; and notes this is a key point of contention in the industry. Some people want all this to be using local LLMs, others want a fully cloud solution.
But hopefully this session will have demystified the process, and given you a strong mental model of how these agents work.
Anna McPhee - Teaching Your Frontend Tools to Talk to AI
(Anna with an AI hallucination that is not her boyfriend)
Anna started with a story of how AI messed up an image manipulation task, because it didn’t have enough context to override the model’s inherent bias. Literally - it replaced her boyfriend with a stranger, when it was meant to be extracting Anna’s photo and putting it on a simple background.
You can also ask an LLM to guess how you look based only on your CV, and it will primarily illustrate the training biases of the model - in Anna’s case, it assumed a software developer must be a white male.
So… imagine what AI is doing to your code. It’s working with limited context. MCP (Model Context Protocol) was developed by Anthropic, trying to create a common language between AI and your tools. The context lives in your tools, MCP gives AI a map.
Example: using Chrome DevTools MCP to evaluate the performance and accessibility of a website on localhost. Sure you can do this yourself but it is quicker to automate; plus connecting it with MCP brings it into the development loop so you can iterate.
Example: Context7 MCP - gives access to up-to-date documentation and best practice guides for common languages, frameworks and tools. Again this brings options into your workflow like checking for outdated code or bad practices. (Sidenote: track token usage when adding Context7 -ed)
Example: Playwright MCP - this has the ability to open a browser and drive it. While designed for testing, people also use it for web scraping.
MCP gotchas:
- the ‘s’ in MCP stands for security - it is a major concern
- it’s not the only tool or protocol
- security again - Filesystem MCP is as dangerous as it sounds
- quality varies wildly - not all MCP agents are equal
- managing API keys becomes a challenge - use env vars
Also - only use MCP if you need to. Many tasks can be done with a CLI, without burning tokens!
Resource: Github MCP Registry
Tamas Piros - When AI Stops Talking and Starts Doing
LLMs have revolutionised the way we work - but while they are great at predicting text, they cannot “do” things. As an example, an LLM can’t book a flight for you. It can only send you off to websites to do it yourself.
We are moving past the novelty stage of LLMs, into the operationalisation, safety and ROI stage. Developers are key enablers for this.
The bridge from talking to doing is MCP. You can create your own MCP servers and clients for, with the risks and caveats already covered in Anna’s talk.
Upsides of MCP solutions
- normalise access to different LLMs
- create sharable, reusable tools
- expand capabilities above the base LL
MCP servers are ultimately APIs, eg. Cloudinary MCP server provides tools to do things like handle files, do visual searches, analyse images and manipulate images (eg. resize, convert format).
Demo: uploading photos from a trip, and getting back a blog post about those photos. Noting the images get resized to 800px width to avoid chewing hundreds of thousands of tokens.
Tamas showed an example where the LLM had added details about a trip that weren’t in any of the photos. You need to have an expert in the loop. Tamas prefers that term over “human in the loop” as the control point still needs to be a subject matter expert - anyone can click ‘approve’ even when they don’t know what they’re talking about. For your own trip you know if the LLM has invented things that didn’t happen.
Beware of “context rot” using MCP servers. Large contexts can be created quickly, and then you get degradation of response quality. This happens in a number of ways with AI, and MCP is no different. You can also burn a lot of tokens.
In future WebMCP will start bridging between websites and MCP servers.
Mandy Michael - Developing a Shared Language for Designers and Engineers
We begin by saying hello to Jello, Mandy’s pooch :)
Mandy is talking about Octopus Deploy’s design system; and her relation ship with Karolina, her design counterpart working on it.
Key pieces to shared language
- people
- guidelines
- tooling
People build understanding, guidelines capture it, tooling reinforces it.
People
- alignment - you aren’t trying to force agreement, you’re trying to arrive at agreement.
- it’s not a checkbox, it’s a relationship.
- work with each other, not around each other
- listen to understand, not to respond
- remember you don’t have to answer right away - it’s ok to take some time to think
- everyone works within their own constraints - try to understand what they are
- respect what everyone brings to the table
Guidelines
- to scale understanding, you need some structure - this is where design systems come in
- people look to your design system for direction
- build and iterate - you can’t move forward if you’re stuck in the weeds
- focus on the goal, don’t try to make every detail perfect
- guidelines are anchors - principles, not rules
- good guidelines start with a shared goal - what problem does the guideline solve?
- show what ‘good’ looks like, and leave room for flexibility in how people meet it
- layer the why/how/what details into the docs
- include guidlines for your own communications
Tooling
- tools need to be aligned with goals
- spreadsheets - you have data to wrangle, use them… particularly for things like audits
- consistency at scale requires automation
- particular callout for Figma Code Connect
- brings code and design together
- has both GUI and CLI options
- has manual and AI-assisted setup options to map your figma and code components
- maps the props between the two systems
- handles nested components
- it can be automated
- Figma MCP
You won’t ever have perfect alignment between everyone, and that’s ok. Work to bring things closer - every connection counts.
mandymichael@bsky.social | mandymichael@front-end.social
Eiji Kitamura - State of identity and authentication on the web
Status quo:
- passwords - we know these both as users and devs
- there are a lot of rules about passwords that are contentious, like how long or “strong” a password needs to be
- actual best practice: create long/complex passwords, don’t use the same password on multiple sites, use a password manager
- …and of all these, using a password manager is the most important; but we can’t force users to do it. This is one of the big reasons 2FA became popular.
- Phishing attacks still bypass many 2FA protections.
Phishing resistant options:
- magic links
- app notification
- security key
- …although these all have their own issues
Passkeys:
- passkeys are a simpler, safer and cost efficient alternative to passwords
- spec: passkeys are a FidoQ standard
- they are asymmetrical, which is safer than symmetric passwords
- the server holds the public key, your client has the private key (passkey)
- local user verification with device biometrics
- passkeys are saved to a password manager, ideally cloud synced in case you lose the device
- resource: goo.gle/passkeys-web
Passkeys vs identity federation:
- use identity federation for new users
- use passkeys for returning users
Identity verification and account recovery:
- status quo includes some terrible approaches like sending photos of ID to organisations
- it’s becoming more common that you can put your license, passport, etc on your smartphone
- spec: Digital Credentials API
- Firebase Phone Number Verification - talks directly to the phone carrier
Building safe and secure systems with passwords is becoming harder, but browsers are offering better options.
@agektmr
Beau Vass - A false sense of accessibility: What automated testing tools are missing.
Automated a11y tools test against a standard eg. WCAG guidelines. But it’s important to remember that guidelines cover quite a lot of requirements, and some require some level of judgement which makes them tricky to test automatically.
Common tools
- WAVE
- AxE DevTools
- Lighthouse
- code linters
- integrated tools - eg. plugins embedded in an app or site
Regardless of what you are using, beware of the nice green 100% success message! The tool never really knows your app is 100% compliant, it has just tested 100% of the things it can test.
An often-cited stat is that automated tools only find about 20-30% of accessibility issues. So yes they’re better than nothing, but it's a pretty low bar and there are a whole lot of things they just can’t detect.
Example: an image…
- The automated tool can tell if there’s an
altattribute; but can’t tell if provide alt text is correct. - It can detect an element with a
role="img"but noaria-label; but not that it’s been applied to the wrong kind of element and will be read out in a confusing manner. - It can detect an
altattribute being present, but not the fact it’s a complex image that really needs alongdescor some other alternative. - and many many other issues
Another example is ‘meaningful sequence’ - eg. a phone plan comparison page, with a ‘best value’ flag on one of the plans. Visually it’s strong, and linked with colour hints; but in source order that flag is actually before the relevant heading and as such is semantically associated with the previous option. In fact in the example, all of the details were in the wrong section.
Captions and transcripts have similar issues to images - the automated check can tell if they are present, but not whether they are correct and synchronised.
Other areas that aren’t easily detected:
- Correct focus management
- Form validation that isn’t being announced
- Visually-hidden labels that have the wrong label (copy-paste error)
- Non-native components that should have ARIA roles but don’t
So we must remember that 20-30% of issues being found leaves 70-80% of issues NOT being found. That’s assuming the number is even true, Beau suspects the success rate is even lower.
Automated testing remains a great way to test large amounts of pages, and to sustain a reasonable minimum standard. But they are a starting point and not the end result. They don’t find everything, and they don’t include the lived experience of people who actually need accessible content.
We have to mention AI… AI is nowhere near being a solution to this problem. AI still has the same limits as other forms of automation, and it’s not been a primary area of investment from the AI industry. It’s more of a “watch this space” than a solution.
What you can do
- build your skills and manual testing ability
- make incremental improvements
- don’t go it alone
- get an accessibility audit
- test with real users
The power of the web is in its universality. Access by everyone regardless of disability is an essential aspect. - Tim Berners-Lee
Tammie Lister - From Components to Prompts: Rethinking Design Systems in the Open
Tammie believes design systems are critical for open source - they allow a wide range of people to contribute to an overall goal. Open systems are more resilient, and open design systems are no exception.
Why open source?
- Shared ownership
- Faster
- Extensibility
- Savings
- Skills out of the box
Challenges of open source
- quality and stability
- divergence of goals
- lack of direct control
- discoverability
Resource: designsystemdiff.com
Tammie created Design System Diff at least partly for the statistics
it collates, eg. the number of unique maintainers is surprisingly low;
and just over 30% can’t be themed. Also, #blameJono, 96.6%
of systems ignore native elements.
How does AI actually apply to design systems? It can enhance the process of using them; and it can help create components in the first place. Either way, AI may suddenly be the first step in everyone’s workflow.
The art of prompting is not to write the shortest prompt, the prompt should be as long as it needs to be.
The vibe cycle has led to an awful lot of things smelling like
shadcn/ui… just as we used to blame Tailwind, or Bootstrap…
Using a first pass and not iterating leads to homegenous output.
AI can help with…
- speed
- consistency
- generation
- prediction
- maintenance
A good tool
- extends capability
- requires human direction
- serves human purposes
We need to evaluate AI against the normal expectations we have of other tools.
What to watch out for using AI?
- hallucinations - try to reduce them with agent instructions, and don’t over-trust
- sameness - if you need flexibility, or to stand out, you will need to diverge somewhere
- stability - is it making things more stable long term?
- ethical issues
MCPs are a trap - they are tools, not complete solutions. You can’t just slap an MCP on things and call it good.
Looking to the future…
Building fresh vs building on top of an existing solution is an important choice for a design system. Don’t assume you should build fresh - it’s often unnecessary. We should stop reinventing things when we don’t need to, particularly when the results aren’t made open.
A call for native systems - how does the ecosystem make better use of the platform?
Transparency as architecture - open systems are the most accessible to machines as well as humans. As AI gets better at creating UI, open systems will do better than closed. The human role is moving away from the repetitive tasks, towards assessing the outputs for quality and suitability. Human expertise isn’t disappearing, it’s being reallocated.
Community solves together - using open source systems lets us respond to challenges faster and better. Future proofing needs investment in the systems that are solving problems the right way.
Katja Forbes - Your Code is the Customer Experience
We have spent decades talking about designing for humans, and for a really long time that was enough. But now the customer is changing. Your next customer may not care about any of the things humans cared about, your next customer may be an algorithm - a delegated agent.
CX is joined by MCX. How do you design for this?
Katja ran through a mocked up/roleplayed conversation with an AI agent. It makes purchasing and scheduling decisions for a lot of highly rational reasons, but not necessarily human ones.
Imagine what this looks like from the point of view of the shop getting product orders placed, or service bookings for a yoga class, by an AI agent…
Marketing uses emotional hooks that AI agents simply don’t respond to. They are cold, hard algorithms. Purchase processes can be a little messy as humans can error-correct, like going back to a homepage and trying an alternative navigation path.
Katja’s mocked up agent goes on to run background checks on organic suppliers, discovering that a vendor had lost its accreditation but continued to sell produce as organic. It triggers a network ban by sharing this information with other agents. Logical, but brutal. Also something the average person might consider doing, but won’t actually do.
You might be tempted to dismiss it as a future problem, but AI commerce is already a thing. Visa, Mastercar, Perplexity, Stripe… multiple companies have released agentic solutions that can make purchases on the consumer’s behalf. Not just executing a pre-made decision, but actually making the purchase decision.
Google has automated the entire customer journey, from inquiry to purchase. There are also legal warning shots being fired between these companies, as they jostle for position in an emerging market.
So the “experience” is unlike anything we’ve designed and coded for before. There is no experience. But the retail version of this is relatively easy to understand, as you can set parameters and let the agent go and find the right thing to purchase. What about B2B?
A B2B example is agentic RFPs. Agents doing the evaluations, instead of bored humans. Walmart has an AI procurement platform in the market already, which closes more than 70% of deals without human intervention (amazingly most vendors prefer it too).
So who is the customer? The human or the agent?
We can’t “ship the org” any more - machine customers don’t care who owns what. The old silos of product, design and dev are collapsing.
Even our concept of business models has changed - adding in IoT and AI creates a whole new suite of categories and opportunities.
The new customer experience is your literal UI code. There are no humans to intervene or error correct, so if the information isn’t there you will simply lose the transaction… and you may not know. The agent won’t stop off and tell you the transaction failed.
The new “experience” principles:
- clarity over cleverness - we don’t need to delight the machine, we need 100% precision
- discoverability through structure - humans explore with intuition, machines parse with logic
- trust built on behaviour, not brand - humans build trust and emotional connections, machines need reliability and verifiable information
Pillars of MCX strategy:
- signal clarity
- reputation via reliability
- intent translation
- AX engagement architecture
Resource: MCX strategy map
There are some possibly surprising impacts, such as machine customers needing accessibility. The investment you’ve made into accessibility is an investment into MCX as well.
This is likely to be very harsh on businesses who cannot signal reliability to machines. If agents can put vendors on a block list, and share that block list, the impact could be fast and severe.
But we do have an opportunity to do something great - to help create new models in a responsible way. Gartner estimate this to be a $30t opportunity, so there will be a lot of investment.
You are writing the rules for a new economy. Do it thoughtfully.























