In my last post, I wrote about my preferred approach for event delegation. I like to attach my event listeners as close as possible to the target elements. Here's how I do that in Reef, a small library my friend Chris Ferdinandi created. It lets you create reactive, state-based components with much less overhead than the big frameworks like React.

The first argument to the Reef constructor is the selector for the element you want to render your UI into. You can pass in a string like #app, but I actually prefer to pass in a direct call to the querySelector() method:

// Create a new Reef instance
var app = new Reef(document.querySelector("#app"), {
data: {
greeting: "Hello",
name: "Kieran"
template: function (props) {
return `${props.greeting}, ${}!`;

I could save it to a variable first, like root, but this would be superfluous. The new Reef instance stores the element under its elem property, meaning I can access the #app element by using app.elem. There's no need to assign it to a variable beforehand, hence the direct call to querySelector().

This means that I can attach my event listeners to app.elem instead of the document or document.body:

// Handle click events inside #app
app.elem.addEventListener("click", handleClick);

// Handle submit events inside #app
app.elem.addEventListener("submit", handleSubmit);

I explained why this is a good idea in my last post. 👍