Skip to content

Conversation

@andylizi
Copy link
Contributor

@andylizi andylizi commented Dec 10, 2025

Preview

Online: https://wasm-website-preview.pages.dev/features/

Motivation

  1. As discussed in [Features] Binaryen toolchain request #495, the feature table is continuously growing (more runtimes & tools). Some kind of redesign was needed to keep the column count reasonable.
  2. The old implementation (mostly written by me) is plain JS that builds the DOM in an ad-hoc way. It has a lot of moving parts tangled together (feature detection, async loading, tooltip logic w/ timers, footnote mappings, etc). It's becoming frustrating to extend, and it's designed to "generate once" which fits poorly for dynamic behavior. A small templating solution would greatly improve maintainability.
  3. The current UI relies on Wikipedia-style tooltips for notes, which I now think are a poor fit:.
    • Every cell has a tooltip that appears on hover and tends to "capture" the cursor when moving between cells.
    • Having a giant list of every note after the table is unwieldy and unnecessary. It reads like a bibliography, and it's growing in length.
    • Semantically speaking, the cells and their notes should be strongly associated, contrary to a "reference" relationship.
    • Keyboard navigation: only cells with footnotes are tabbable, which feels a bit inconsistent. Not sure if this is actually a problem for Assistive Technology users though.

Design decisions

  • Filtering (addressing motivation 1): this PR uses checkboxes to toggle column categories (Web Browsers, Standalone Runtimes, Tools). While this does the job for now, I'm not super in love with this design and would welcome ideas.
    • Categories are hard to balance: Standalone Runtimes currently dominate while the others are sparse. This would worsen as more runtimes are added.
    • It's tricky to make the categories balanced. Right now, Standalone Runtimes have too many columns and the other two too few. We would still run into the columns problem in the future, when there're more server runtimes added.
    • Multiple stacked tables isn't great, the page is already very long vertically.
    • Multiple pages would hurt discoverability and prevent cross-category comparison. And it doesn't address the unbalanced problem.
  • Visual style (addressing motivation 3): heavily "inspired" by MDN's browser compatibility table (example). Their design works really well here. I emulated the look & feel without looking at their code, so I think it should avoid license issues? Otherwise, since their site uses MPL, a file-based copyleft license, we can make the relevant files MPL to be extra safe.
  • JS framework (addressing motivation 2): I used Alpine.js as a minimal framework, because it is the only option AFAIK that doesn't require a (JS-based) build step. Our current build process is Ruby-based and hasn't been touched in 8+ years, so I didn't dare to make changes. Let me know if we'd like to explore alternative approaches.

Current status

This is still a work-in-progress, the code is not ready yet, and I'd appreciate early feedback on whether the overall direction looks reasonable. I know large changes can be difficult to review with the project's limited bandwidth. If an incremental path would be preferable, I'm happy to take that route instead. I just don't have a clear idea to do this cleanly under the constraint of the existing code, so suggestions are very welcome. Thanks everyone for the input! I'm working on polishing and getting it ready for reivew.

Remaining work

  • Accessibility
  • More comments to document the code
  • Graceful degradation for older browsers (notably Firefox ESR, which came up before)
  • Clean up code structure
  • Loading state / error handling

@jryans
Copy link
Contributor

jryans commented Dec 10, 2025

As a random bystander, I personally like the design overall! The MDN style works well here.

You may need to tweak the design a bit for mobile, as currently I notice a few issues:

  1. Toggle row at the top seems to keep going off screen and some items are inaccessible
  2. When expanding a cell to see notes, you have to scroll horizontally to read the notes
image

@rossberg
Copy link
Member

Nice, I also like the redesign. A few comments:

  • I think "Server runtimes" is not quite the right name, since servers are just one of many environments they're used in. I'd suggest "Standalone runtimes". (OTOH, the imbalance in category sizes doesn't bother me.)

  • When the Web Browsers category is turned off, I'd expect the "Your browser" column to be hidden as well.

  • The page background appears to adjust to Dark Mode, but then some of the text colors become hard to read, especially black:

    Screenshot 2025-12-10 at 08 15 44

    (Generally, the current page looks somewhat nicer in Dark mode, with less prominent borders and alternating background shades instead, but I'm sure that can be tweaked.)

  • Personally, I'd have a slight preference for keeping the tooltips, and just removing the footnotes. Tooltips are more intuitive and much quicker to use, especially when you want to inspect several entries. But that may be subjective.

@redianthus
Copy link
Contributor

It looks very nice!

I think maybe we should have the ability for a project to belong to more than a single category? For instance, Owi features both a "standalone runtime", and some "tooling" (symbolic execution, formatter etc.).

@keithw
Copy link
Member

keithw commented Dec 10, 2025

wasm2c probably belongs more in "standalone runtimes" than "tools" (maybe both, but if I had to pick one it would be "standalone runtimes").

@andylizi
Copy link
Contributor Author

andylizi commented Dec 17, 2025

Thanks everyone for taking a look! I've pushed my revised version: same link as before.

Outdated demo video
demo.webm
  • Toggle row at the top seems to keep going off screen and some items are inaccessible

Should be fixed now!

  • When expanding a cell to see notes, you have to scroll horizontally to read the notes

Good catch! Now the notes are fixed to the left side on mobile view (just like the row headers), with maximum width restricted to viewport, should be a lot better now.

  • I think "Server runtimes" is not quite the right name, since servers are just one of many environments they're used in. I'd suggest "Standalone runtimes"

Makes sense, I now have "Standalone runtimes" and "Embedded runtimes", although the latter one is currently unused: there are some library-only engines out there, but everything on the table right now have a CLI binary.

  • When the Web Browsers category is turned off, I'd expect the "Your browser" column to be hidden as well.

Good point, fixed!

  • The page background appears to adjust to Dark Mode, but then some of the text colors become hard to read, especially black

This is quite curious, the foreground text color is supposed to automatically change due to the color-scheme: dark CSS property, and it's working on my side (both Chrome and Firefox Windows). I'm not sure why it's broken for you and @jryans but only inside the shadow DOM. Probably some shenanigans going on here...

But anyway, I felt like the shadow DOM implementation is becoming more trouble than it's worth, so I decided to get rid of it. Dark mode should be a lot better now!

  • (Generally, the current page looks somewhat nicer in Dark mode, with less prominent borders and alternating background shades instead, but I'm sure that can be tweaked.)

Yeah definitely tricky to get borders to look right in dark mode. I tried using striped rows like before, but can't get it to look good with the new design either. So went with a new approach. Let me know how it looks now!


  • Personally, I'd have a slight preference for keeping the tooltips, and just removing the footnotes. Tooltips are more intuitive and much quicker to use, especially when you want to inspect several entries. But that may be subjective.

I appreciate the feedback on tooltips, it's true that they're quick and intuitive for inspecting multiple cells. My main concern with the intuitiveness of the click-to-expand pattern is the lack of affordance, i.e. it's not obvious that the cells can be clicked. This is especially true for touch screen users, who don't see hover states.

I've made two changes to mitigate the issue:

  1. I changed the icon for "there are notes for this cell" from an asterisk to three dots ellipsis, which usually means "more options" or "expand" in UI language. I'm hoping this conveys that something is there to click on.
  2. MDN has this tip at the bottom of their tables "Tip: you can click/tap on a cell for more information.", so I added a line to this effect as well: "The table below aims to track implemented features in popular engines. You can click on a cell for more information."

I felt the display-on-hover tooltips might be a bit too attention grabbing. I'd expect that most of our visitors won't be interested in the exact way to enable experimental features. Consider the possible user stories:

  1. As a wasm app developer, I want to know if a feature is safe to use across my users' environments.
  2. As a spec follower, I want to track standardization progress of features.
  3. As someone deploying wasm apps, I want to compare runtime capabilities and research which one I should choose.
  4. As runtime/tooling developer, I want to know what other projects have implemented.
  5. As an early adopter, I want to enable experimental features for development.
  6. As an end user, I want to troubleshoot "unsupported feature" errors when running wasm, but this information is not provided by the developer, and I have to find out myself.

In all of these scenarios, information like "This feature requires flag --wasm=exceptions" is only relevant for the last two. For others, merely knowing the feature is still experimental would be enough. That's why I feel it's best not to distract users with popups when they mouse over the table. If they wanted to know, say, how to enable branch hinting in Node.js, they can click on that specific cell to find out, which seems like the right balance between quick scanning and detailed exploration.


I think maybe we should have the ability for a project to belong to more than a single category? For instance, Owi features both a "standalone runtime", and some "tooling" (symbolic execution, formatter etc.).

wasm2c probably belongs more in "standalone runtimes" than "tools" (maybe both, but if I had to pick one it would be "standalone runtimes").

There are definitely some blurry lines here. I think a good way to approach classification is to consider the categories from a practical standpoint. In my view,

  1. Runtimes are used by developers and end users, and they run in production.
  2. Tools are used by developers, and they run only during development.

I feel this distinction matters a lot because, developers generally have little control over what runtimes and/or versions their user is using. That's why resources like caniuse.com and this feature table is especially useful for decision making. In contrast, developers have full control over toolchains involved in the development process. If a feature I want is only available in latest wasm-opt, well I'll just use the latest wasm-opt then. Furthermore, wasm toolchains are nice but usually not mandatory. If wasm-opt doesn't support my use case yet, I can made the trade-off to not use it. But I generally cannot tell my users to "just stop using Safari" (as much as I'd love to do that at times).

I'm not super familiar with Owi so might be missing nuance there, but just from looking over the documentation, the project seems to really focus on the development phrase:

Owi is an automatic bug-finding tool for C, C++, Go, Rust and Zig.
Owi includes a cross-language symbolic execution engine supporting: Automated testing, bug finding and pentesting; Solver-aided programming; Test case generation; Formal verification;
Owi offers a set of practical tools for Wasm development and analysis: [...] These tools aim to support everyday development tasks as well as research on program analysis, fuzzing, and program transformation.

While it's true that the symbolic execution engine can execute code (really cool concept btw!), my impression is that it's mostly not designed for use in a production wasm environment, which is why I think it fit the Tools category better according to the reasoning above.

There is also another important practical consideration here. The primary motivation for adding the categories is to display fewer columns by default, so some kind of differential treatment is unavoidable here. Owi aside, it's also true that wasm2c (while self-identifying as a tool as well) does generate binaries that run in production (broadly speaking, even though it might not fit the narrow definition of a runtime). But by the same token, Binaryen includes a tool wasm2js which compiles wasm to JavaScript. If wasm2c is a runtime, wasm2js definitely is as well. Thus we find ourselves in a rather humorous situation where all tools are secretly runtimes, and there is nothing left in the Tools category.

Apologies for the long-windedness, I thought I should give my two cents and it turned out like this😂.
Any input would be greatly appreciated!

@redianthus
Copy link
Contributor

While it's true that the symbolic execution engine can execute code (really cool concept btw!), my impression is that it's mostly not designed for use in a production wasm environment, which is why I think it fit the Tools category better according to the reasoning above.

Yes, what I meant is: there is a symbolic interpreter in Owi (owi sym) and it do belongs to the tool category, but there is also a regular, concrete interpreter owi run (like Wizard, Wasmtime, Wazero, Chicory, Wasmer, GraalWasm or WasmEdge). This is not what we advertise on the GH page, but it is a quite decent one, well tested (with its own fuzzer, and passing the whole reference test-suite) and I think it has decent performances. It has already been successfully ran in MirageOS unikernels, which is clearly a case where it can be considered as "running in production as a Wasm runtime".

@tomayac
Copy link
Collaborator

tomayac commented Dec 17, 2025

As you're touching the CSS anyways, the wazero logo almost disappears in dark mode. Not sure if anyone from wazero reads this and can advise on branding guidelines, but a simple invert for this particular logo would likely do the job.

@jryans
Copy link
Contributor

jryans commented Dec 17, 2025

There’s still a small issue with the revealed details, at least in mobile iOS browsers:

image

I assume the flag explanation should move to a second line instead of being partially offscreen.

Other that that, looking good to me. 😄

@andylizi andylizi mentioned this pull request Dec 18, 2025
@andylizi
Copy link
Contributor Author

andylizi commented Dec 18, 2025

Latest preview: still the same link.

but there is also a regular, concrete interpreter owi run

Ah yes I missed that, thanks for pointing it out! Yeah that makes sense, if nobody objects I'll added Owi to the Standalone Runtimes category as well.

The table now supports specifying multiple categories, with the first one being primary. If both Runtimes and Tools are selected, Owi will be listed under Tools. If Tools is not selected, Owi will be listed under Runtimes. That should hopefully be a consistent way to handle everything.

As you're touching the CSS anyways, the wazero logo almost disappears in dark mode. Not sure if anyone from wazero reads this and can advise on branding guidelines, but a simple invert for this particular logo would likely do the job.

Done!

There’s still a small issue with the revealed details, at least in mobile iOS browsers:

Looks like a Safari quirk with SVG sizes, should be fixed now!


With the design issues mostly settled, I will start working on polishing and getting the code ready for review. Thanks again for all the feedback!

@keithw
Copy link
Member

keithw commented Dec 18, 2025

wasm2c would still like to be in "standalone runtimes" instead of "tools," please. (The output of wasm2c is not really usable for anything except running it.)

I do think it's great to have a "tools" category -- there should definitely be a column for the Bytecode Alliance wasm-tools (and probably the CG WABT tools as well). E.g. both wasm-tools and WABT implement a wasm2wat/wat2wasm, wasm-validate, etc. This can be a separate PR after this goes in.

@andylizi
Copy link
Contributor Author

wasm2c would still like to be in "standalone runtimes" instead of "tools," please. (The output of wasm2c is not really usable for anything except running it.)

Got it.

The table now shows 14 columns by default; we might need to come up with something else soon, but that can be left to the future.

table th {
font-weight: 600;
padding: 8px 12px;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
}
white-space: nowrap;
}

This avoids the line breaks in "wasm-language-tools". I think it looks a little better than with the line breaks, especially as "GraalWasm" is also quite long and has a relatively narrow logo.

Image

Copy link
Contributor Author

@andylizi andylizi Dec 22, 2025

Choose a reason for hiding this comment

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

I've disabled the line breaks, and the text does look better without. Still, the fact that the column is more than two times wider than the others looks a bit off to me. Not sure how I feel about it 🤔 I guess it's a fine trade-off either way

@g-plane
Copy link
Contributor

g-plane commented Dec 20, 2025

Some ideas:

  • <thead> can be sticky, which is helpful when scrolling down.
  • Categories checkboxes state can be stored and synced to URL search params so I can share this page with pre-selected categories to others.

@andylizi
Copy link
Contributor Author

I'm finished with accessibility and tested it using NVDA with Chrome and Firefox on Windows.

Latest preview: link

  • <thead> can be sticky, which is helpful when scrolling down.

Sticky headers can be quite tricky to implement with just CSS. It's easy for row headers because the table itself overflows on the x-axis. But on the y-axis, the table doesn't overflow, the entire viewport does. I tried a few things, but there seems to be no way to implement it without JavaScript, as far as I'm aware.

  • Categories checkboxes state can be stored and synced to URL search params so I can share this page with pre-selected categories to others.

Great idea, done!

.content.firstElementChild.cloneNode(true);
const url = new URL(location.href);
if (queryKeys.length) {
url.searchParams.set('categories', queryKeys.join(','));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
url.searchParams.set('categories', queryKeys.join(','));
queryKeys.forEach((queryKey) => url.searchParams.append('categories', queryKey));

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/append

function loadSelectedCategories(allCategories) {
const names = new URLSearchParams(location.search)
.getAll('categories')
.flatMap((values) => values.split(','))
Copy link
Contributor

@g-plane g-plane Dec 22, 2025

Choose a reason for hiding this comment

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

Suggested change
.flatMap((values) => values.split(','))

Search params will be categories=browsers&categories=tools with the previous changes so we don't need flatMap any more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants