Declarative DOM Interactions

A lightweight JavaScript library to define behavior directly in your HTML using attributes. Handle events, make requests, and update the DOM without writing custom JavaScript.

View on GitHub

The Perfect Blend

Mate.js allows you to quickly and expressively build dynamic frontends. It introduces custom attributes to map events directly to DOM mutations and requests, keeping your logic right in your markup.

There are two syntaxes available:

Installation

Option 1: NPM (Recommended)

import mate from '@nsanta/mate/mate.js';

// Initialize the library
mate();

Option 2: CDN

Include Mate.js directly in your HTML:

<!-- Add this to your HTML head or before closing body tag -->
<script src="https://cdn.jsdelivr.net/gh/nsanta/mate/dist/bundle.js"></script>

The `mx-*` Syntax

The recommended mx-* syntax provides a concise, event-centric way to define behavior.

mx-{EVENT}[.modifiers]="{ACTION|CAPABILITY.method}[:{PRESENTATION}[:{TARGET}]]"

Events & Actions

Bind to any standard DOM event using mx-{event}.

mx-click="@request:@inner" triggers an HTTP request on click and replaces the element's inner HTML.

Modifiers

Chain modifiers directly to the event name to alter behavior seamlessly.

mx-input.debounce.500ms="..." debounces input. .prevent.stop controls event propagation.

Presenters & Targets

Decide exactly where the response goes in the DOM.

Use :@id:result or :@class:items to target elements, or :@prepend / :@append to insert content.

Examples & Patterns

Basic Click Request

Click a button to make a request and update the DOM automatically.

<button mx-click="@request:@inner" mx-path="/api/data">
  Load Content
</button>

Update Element by ID

Click one element to update an entirely different element on the page.

<button mx-click="@request:@id:result-box" mx-path="/api/data">
  Load into Output Box
</button>

<div id="result-box">Content will appear here</div>

Modifiers: Debouncing Search

Wait until the user stops typing to fire the request.

<input type="text" 
       placeholder="Search..."
       mx-input.debounce.500ms="@request:@inner" 
       mx-path="/api/search" />

Controllers for Complex State

For custom logic, map events directly to custom controller methods.

<div mx-controller="Counter">
  <span>Count: <span id="count">0</span></span>
  <button mx-click="@event:@controller:increment">+</button>
  <button mx-click="@event:@controller:decrement">-</button>
</div>

Why Mate.js?