HTML is getting cool again: Meet the Invoker Commands API
For years, frontend development has had a slightly embarrassing relationship with HTML. We all read...
개요 #
버튼을 눌러 다이얼로그를 여는 코드. 프론트엔드 개발자라면 백 번은 써봤을 그 코드가 이제 HTML 속성 두 개로 줄어든다. Invoker Commands API는 버튼과 제어 대상 요소의 관계를 commandfor와 command 속성으로 선언한다. 이벤트 리스너도, 상태 변수도 필요 없다.
MDN은 이 API를 Baseline 2025로 분류하고 있으며, 2025년 12월부터 최신 브라우저에서 크로스 브라우저 지원이 시작됐다.
Alexandra는 이 변화의 핵심이 코드 열 줄을 줄이는 데 있지 않다고 짚는다. 우리가 떠맡고 있던 책임이 브라우저로 되돌아간다는 점이 진짜 의미다.
지금까지는 이렇게 썼다 #
다이얼로그 하나를 열고 닫으려면 정형화된 보일러플레이트가 따라붙었다.
<button id="open-dialog">Open dialog</button>
<dialog id="my-dialog">
<p>Dialog content</p>
<button id="close-dialog">Close</button>
</dialog>
<script>
const dialog = document.getElementById("my-dialog");
document.getElementById("open-dialog").addEventListener("click", () => {
dialog.showModal();
});
document.getElementById("close-dialog").addEventListener("click", () => {
dialog.close();
});
</script>버튼과 다이얼로그를 만들고, 그다음 "사용자가 버튼을 클릭하면 다이얼로그를 열어라"를 브라우저에게 JS로 설명해준다.
React나 Vue를 쓰면 오히려 더 번거로워진다. 상태를 하나 만들고, 컴포넌트로 내려보내고, 이벤트 핸들러를 연결하고, 그 전부가 어긋나지 않게 관리해야 한다.
바닐라든 프레임워크든 위 코드 자체에 문제는 없다. 다만 천 번째로 같은 코드를 쓰다 보면 의문이 남는다. 다이얼로그가 열려 있다는 사실을 표현하려고 애플리케이션 상태까지 동원해야 할까?
정답은 "경우에 따라"다. 상태가 진짜 필요한 순간도 있다. 하지만 2026년의 HTML과 브라우저가 이미 기본 제공하는 동작을 우리가 다시 만들고 있는 경우도 적지 않다.
Invoker Commands API가 하는 일 #
이 API는 버튼에 동작을 선언적으로 부여하고, 그 버튼으로 인터랙티브 요소를 제어하게 해준다. 이벤트 리스너를 붙이는 대신 관계를 HTML에 그대로 적는다.
핵심 속성은 두 개다.
commandFor: 버튼을 "command invoker"로 만든다. 값으로 제어할 요소의 ID를 받는다.command: 그 요소에 수행할 동작을 지정한다.
<button commandfor="mycoolpopover" command="toggle-popover">
Toggle the popover
</button>
<section id="mycoolpopover" popover>
<button commandfor="mycoolpopover" command="hide-popover">Close</button>
Awesome Popover content
</section>
Photo by César Gaviria on Pexels
React에서는 어떻게 쓰나 #
여기 나오는 내용은 쓰고 있는 프레임워크에 그대로 옮겨도 된다.
export function DeleteButton() {
return (
<>
<button command="show-modal" commandFor="delete-dialog">
Delete account
</button>
<dialog id="delete-dialog">
<h2>Delete account?</h2>
<p>This cannot be undone.</p>
<button command="close" commandFor="delete-dialog">
Cancel
</button>
</dialog>
</>
);
}한 가지 놓치기 쉬운 지점이 있다. JSX 프로퍼티는 commandFor지만, 실제로 만들어지는 HTML 속성은 소문자 commandfor다.
코드 열 줄이 전부는 아니다 #
처음 보면 열 줄 정도 아끼는 기능처럼 보인다. 그것도 나쁘지 않다. 하지만 더 흥미로운 건 책임이 개발자에게서 브라우저로 옮겨간다는 점이다.
JavaScript를 덜 쓴다고 브라우저가 덜 유능해지는 게 아니다. 오히려 반대다. 브라우저가 유능해졌으니 우리가 JS를 덜 써도 되는 것이다.
브라우저 지원 #
다이얼로그 코드를 전부 지우기 전에 짚어둘 게 하나 있다. Invoker Commands API는 새 기능이다. MDN은 현재 Baseline 2025로 표기하고 있고, 2025년 12월부터 최신 브라우저 버전에서 크로스 브라우저 지원이 이뤄지고 있다. 구형 브라우저에서는 동작하지 않을 수 있다.
참고 링크 #
- MDN — Invoker Commands API
- MDN —
<button>element - MDN —
<dialog>element - MDN — Using the Popover API
이 글은 위 출처를 바탕으로 한국 독자를 위해 재작성한 기사입니다. 원문의 사실과 수치에 근거하며, 별도의 견해를 포함하지 않습니다.
