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 is a clean, event-centric syntax available:
mx-*syntax: An event-centric shorthand with powerful modifiers.
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/mate.global.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. Key modifiers like .enter, .ctrl, .right filter by specific keys and buttons.
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" />
Key Modifiers
Filter keyboard and mouse events by specific keys or buttons.
<!-- Only fire on Enter key --> <input mx-keydown.enter="@request:@inner" mx-path="/search" /> <!-- Ctrl+Enter shortcut --> <input mx-keydown.enter.ctrl="@request:@inner" mx-path="/save" /> <!-- Only right-click --> <button mx-click.right.prevent="@request:@inner" mx-path="/context"> Right click me </button>
Key name: .enter .tab .esc .space |
System: .ctrl .shift .alt .meta |
Mouse: .left .middle .right
Framework Integration (React, Vue, Svelte)
Render framework components as presenters — mate.js handles connectivity, your framework handles presentation.
<!-- React component as presenter --> <button mx-click="@request:@react:ProfileCard" mx-path="/api/profile"> Load Profile </button> <!-- Vue component as presenter --> <div mx-load="@request:@vue:Dashboard" mx-path="/api/dashboard"></div> <!-- Svelte component with streaming --> <button mx-click="@stream:@svelte:LogViewer" mx-path="/api/logs"> Stream Logs </button>
Register components via registerComponent('Name', Component) from @nsanta/mate/react, @nsanta/mate/vue, or @nsanta/mate/svelte.
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?
- Lightweight: Tiny footprint, bringing declarative logic without a heavy framework runtime.
- Extensible: Easily register custom Capabilities and Presenters.
- Progressive Enhancement: Perfect for augmenting server-rendered HTML (HTMX-style).
- Declarative: Keep your interactions readable directly within the markup layout.