Invokers are the coolest HTML API that you aren’t using. This is right about to drop in all major browsers. It’s available in Safari Technology Preview and Firefox and Chrome already. It is so cool.
I want you to support my original content as well please, below is the link:
HTML Invokers: The Coolest API You Aren’t Using Yet
So, what are invokers?
The Big Idea
Invokers let your buttons actually do stuff without JavaScript. Like, at all. You just tell the button what element to control and what to do with it. That’s the whole thing.
It’s wild that this hasn’t existed until now.
How We’ve Been Doing It (The Old Way)
Right now, if you want a button to open a dialog, you’re writing code like this:
const button = document.querySelector('#open-button');
const dialog = document.querySelector('#my-dialog');
button.addEventListener('click', () => {
dialog.showModal();
});
It works, but come on. That’s way too much ceremony for “button opens thing.”
How Invokers Work (The New Way)
You add two attributes to your button, and you’re done:
<button commandfor="my-dialog" command="show-modal">
Open Dialog
</button>
<dialog id="my-dialog">
<h2>Welcome!</h2>
<p>This dialog opened without a single line of JavaScript.</p>
<button commandfor="my-dialog" command="close">
Close This
</button>
</dialog>
That’s it. The button just knows what to do. No JavaScript file. No event listeners, no querying the DOM. It’s beautiful.
A Real-World Example
Here’s something you’d actually build — a settings menu with a popover:
<button commandfor="settings-menu" command="toggle-popover">
⚙️ Settings
</button>
<div id="settings-menu" popover>
<h3>Settings</h3>
<label>
<input type="checkbox"> Dark Mode
</label>
<label>
<input type="checkbox"> Notifications
</label>
<label>
<input type="checkbox"> Auto-save
</label>
<button commandfor="settings-menu" command="hide-popover">
Done
</button>
</div>
Click the settings button, the menu pops up. Click Done, it closes. Zero JavaScript required. This used to take 20+ lines of code.
The Attributes
There are two attributes that make this magic happen:
` - This points to the ID of whatever you want to control. So if you want to control a dialog with id="my-dialog", you write commandfor="my-dialog"`.
` - This is what you want to happen. Like show-modal to open a dialog, or close to close it, or toggle-popover` for popovers.
That’s literally all you need to know.
What You Can Control
Right now, you can control:
Dialogs: show-modal and close work right out of the box. Finally.
Popovers: show-popover, hide-popover, and toggle-popover. Super clean.
Details Elements: open, close, and toggle for accordion-style content.
And they’re adding more. File inputs, video controls, all that stuff is coming.
Custom Commands Are Cool Too
You can make up your own commands. They just need to start with two dashes:
<button commandfor="photo" command="--flip-horizontal">
Flip Photo
</button>
<button commandfor="photo" command="--rotate-90">
Rotate 90°
</button><img id="photo" src="vacation.jpg" alt="Beach photo">
Then you write a little JavaScript to listen for these custom commands and do whatever you want:
document.getElementById('photo').addEventListener('command', (e) => {
if (e.command === '--flip-horizontal') {
e.target.style.transform = 'scaleX(-1)';
} else if (e.command === '--rotate-90') {
e.target.style.transform = 'rotate(90deg)';
}
});
But the whole click-handling setup is already done for you, which is nice.
Another Solid Example: Image Gallery
Here’s a complete image gallery with next/previous buttons:
<div class="gallery">
<button commandfor="gallery-dialog" command="show-modal">
📷 View Gallery
</button>
</div>
<dialog id="gallery-dialog">
<div class="gallery-content">
<img id="current-image" src="photo-1.jpg" alt="Gallery photo">
<div class="controls">
<button commandfor="current-image" command="--previous">
← Previous
</button>
<button commandfor="current-image" command="--next">
Next →
</button>
<button commandfor="gallery-dialog" command="close">
✕ Close
</button>
</div>
</div>
</dialog>
The dialog opens and closes with built-in commands. The next/previous buttons use custom commands that you’d wire up with a few lines of JavaScript. But all the button-clicking mechanics? Already handled.
Browser Support Right Now
Here’s where things stand:
- Chrome Canary 134+ Turn on the experimental flag
- Firefox Nightly 135+ Enable the flag
- Safari Technology Preview Flag it on
It’s in the experimental phase, but it’s moving fast. This should be available everywhere by mid-2025.
Why This Is Actually a Big Deal
Look, this isn’t changing the world or anything. But it’s fixing something that’s been annoying for years.
Buttons controlling other elements is foundational web stuff. We shouldn’t need to import libraries or write boilerplate for it. HTML should just handle it. And now it does.
Plus, when stuff is built into the platform, accessibility comes for free. Screen readers work better with it. Keyboard navigation just works. You don’t have to remember to add all the ARIA attributes.
Real Talk
This is one of those features that makes you go “wait, this wasn’t already a thing?” Because it feels so obvious once you see it.
The web platform is finally catching up to what we’ve been doing with JavaScript frameworks for years. And that’s great because it means less JavaScript to ship, less code to maintain, and websites that just work better.
Invokers are simple, they’re elegant, and they’re about to be everywhere. Get ready to delete a bunch of event listeners.
The Bottom Line
HTML Invokers let buttons control stuff without JavaScript. Two attributes. No libraries. It’s clean, it’s simple, and it’s coming to browsers near you.
This is the kind of improvement that makes web development just a little bit more fun. And honestly? We could use more of that.
Did you learn something good today as a developer?
Then show some love.
© Muhammad Usman
WordPress Developer | Website Strategist | SEO Specialist
Don’t forget to subscribe to Developer’s Journey to show your support.

Top comments (0)