m2d2
v3.1.1
Published
A very easy, clean and extensible way to build interactive web-based user interfaces.
Readme
M2D2
v3.0: M2D2 has been rewritten in TypeScript. The library is consumed identically (
m2d2.ready($ => ...),const $ = m2d2.load()). See CHANGELOG.md for the documented behavior changes. All extensions (alert, lang, storage, xhr, upload, ws) are included.
Quick Start | Documentation | Recommendations | Install | Tutorial | Examples
Extensions: Alerts | Language | Storage | XHR | Upload | WebSocket
A class to easily place data in DOM and update them immediately upon change. It has no dependencies. It is similar to Angular, Vue, ReactJS and alike frameworks and shares some similarities with JQuery.
The main goal of this framework is to keep the HTML and JS pure and clean, without having to either setup rules in the HTML (like in Angular), use HTML templates inside Javascript like in React, or use mixed templates like Vue.
If you know Javascript and HTML you pretty much know 98% of M2D2 already. Because of that, it has a small learning curve, so you don't need to spend hours trying to understand how the framework works or how you can apply it to your work.
This framework can work together with any other as it is just pure Javascript. Although, once you use it, you will like how clean your code can be.
Is M2D2 for you?
These are some reasons why you may be interested in using M2D2:
- [ ] I deploy mainly for modern browsers (no Internet Explorer, for example)
- [ ] I like to keep my HTML and my Javascript codes clean and simple
- [ ] I like Javascript, but I would like to update the HTML in an easier way
- [ ] I have used JQuery, but I want to make my code to react to value changes automatically
- [ ] I don't want to spend too much time in learning a new framework
- [ ] I really don't like to have all my code in a single file
- [ ] I have some JQuery or Javascript libraries that I would like to use
- [ ] I don't want very complicated codes to achieve simple things
If you checked one or more of the above boxes, M2D2 will suit you well.
Framework/Library comparison:
| | M2D2 | JQuery | Angular | ReactJS | Vue | |---------------------------|------|--------|---------|---------|-------| | Size | 19Kb | 88Kb | 60Kb | 166Kb | 181Kb | | Easy to learn | Yes | Yes | No | No | No | | Clean and standard HTML | Yes | Yes | No | Yes | No | | Clean Javascript | Yes | Yes | Yes | No | Yes | | Good for small projects | Yes | Yes | No | Yes | Yes | | Good for large projects | Yes | No | Yes | Yes | Yes | | Observe object changes | Yes | No | Yes | Yes | Yes | | Large community | No | Yes | Yes | Yes | Yes |
Repositories (synchronized):
- https://gitlab.com/intellisrc/m2d2/
- https://github.com/intellisrc/m2d2/
Hello World
// When DOM is ready...
m2d2.ready($ => {
// Place text in #myid :
$(myid, "Hello World");
// Then, change it into something else:
myid.text = "Hola Mundo";
});To better understand how M2D2 works, let's imagine you have this object:
const user_data = {
user_id : 1289943,
first_name : "Beth",
middle_name : "Eleonor",
last_name : "Wilson",
age : 35,
emails : [
"[email protected]",
"[email protected]"
]
}Now, we want to place that information in this HTML:
<div id="user">
<div><span>ID:</span><span class="user_id"></span></div>
<div><span>First Name:</span><span class="first_name"></span></div>
<div><span>Middle Name:</span><span class="middle_name"></span></div>
<div><span>Last Name:</span><span class="last_name"></span></div>
<div><span>Age:</span><span class="age"></span></div>
<div>
<span>Emails:</span>
<ul class="emails"></ul>
</div>
</div>This is what you need to code (for example: user.js):
m2d2.ready($ => {
const user = $("#user", user_data);
})And that's it! ... But what if user_info doesn't match our HTML structure?
for example this one:
<div id="user">
<div><span>Name:</span><span class="name"></span></div>
<div><span>Email:</span><span class="email"></span></div>
</div>m2d2.ready($ => {
// Assuming we don't have empty fields (for simplicity)
const user = $("#user", {
dataset : { id : user_info.user_id }, // will create `data-id=` attribute in `#user`
name : user_info.first_name + " " + user_info.middle_name[0].toUpperCase() + ". " + user_info.last_name,
email : user_info.emails[0]
});
})... and that's it! ... But what if you need to interact with it (using events) ?
m2d2.ready($ => {
const user = $("#user", {
/* ... */
email : {
text : user_info.emails[0],
onclick : function(ev) {
window.location.href = "mailto:" + this.text;
}
}
});
})... and that's it! ... But what if ... ?
Read the documentation, try the tutorial or the examples:
Quick Start:
General Recommendations
Best practices when using M2D2
Tutorial:
Live Demo:
Stand-alone html + js examples
Documentation:
Install
You can use this library either with Web or NodeJS, Framework7, etc.
For the Web
Option 1 : Get M2D2 using npm / yarn
npm i m2d2
or
yarn add m2d2
Then you will find the library files under node_modules/m2d2/dist/ (more about this below).
Option 2 : Direct download
All extensions included: m2d2.min.js — set it in the HTML head.
Option 3 : CDN
To use it:
m2d2.ready($ => {
// your code here
});As Module
Using npm:
npm i m2d2
Then you will use it something like:
import m2d2 from 'm2d2';
const $ = m2d2.load();The npm package includes full TypeScript type declarations (.d.ts).
You can use it together with JQuery, or with Framework7 or any other framework of your choice.
Extensions:
Alert
This extension makes it easy to display alerts, confirmation, input dialogs and more. Uses Unicode icons by default (no font dependency), with pluggable icon sources (Material, Font Awesome, SVG) and modern CSS themes (light/dark).
Example:
$.confirm("Are you sure?", "This is important", res => {
if(res) {
// Do something
}
});Configure once at startup:
m2d2.alert.register({
icons: "material", // "default" | "material" | "fa" | "svg"
theme: "dark", // "light" | "dark"
iconsOff: false // disable icons entirely
});Storage
This extension provides an easy way to save and restore data into localStorage and sessionStorage.
Example:
// Store something in the localStorage:
$.local.set("key", { age: 20 });
console.log($.local.get("key"));Lang
With this extension you can handle multiple languages easily.
Example:
$.lang('fr');
const _ = $.dict;
console.log(_("yes"));XHR
This extension handles almost any kind of HTTP request to a server (e.g., GET, POST, PUT, DELETE, etc.)
Example:
$.put("/my/url", { name : "Tony" }, res => {
// res = response from server
});Upload
This extension makes it easy to upload files to a server via XHR (included in XHR bundle).
Example:
$("uploadFileButton", {
onclick : function(event) {
$.upload(event, {
upload : "example.com/upload/",
field : "file",
onDone : (response, allDone) => {
console.log("Uploaded");
}
});
}
});WS
This extension gives you an easy-to-use WebSocket client.
Example:
$.ws.connect({
host : "example.com",
path : "ws/",
secure : true, // for wss://
request : {} // initial request
}, json => {
// json is the data received from server
if(json.user) { /* ... */ }
});
// Send a message to server:
$.ws.request({
user : { id : 1000 }
});Bundles:
As of v3.0, there is a single bundle that includes core + all extensions (alert, lang, storage, xhr, upload, ws). It is available in three formats:
| File | Format | Use case |
|------|--------|----------|
| m2d2.min.js | IIFE (browser global m2d2) | <script> tag in HTML |
| m2d2.cjs.js | CommonJS | require() in Node |
| m2d2.esm.js | ESM | import in bundlers / Node ESM |
Import:
import m2d2 from 'm2d2'; // ESM — includes all extensions
const $ = m2d2.load();const m2d2 = require('m2d2'); // CommonJS
const $ = m2d2.load();TypeScript types are included automatically (dist/index.d.ts).
What's New in version 3.0:
M2D2 has been rewritten in TypeScript. The source is now modular (src/ with
focused modules) and compiled to ESM, CJS, and a browser IIFE bundle with full
type declarations. The public API is unchanged. See
CHANGELOG.md for the complete list of bug fixes and behavior
changes.
The alert extension has been redesigned with a cleaner architecture:
pluggable icon sources (Unicode default, Material Symbols, Font Awesome, SVG),
modern CSS themes (light/dark via CSS variables), and a single configuration
point (m2d2.alert.register({ icons, theme, ... })).
What's New in version 2.0:
This library was almost completely rewritten in v2.0. The main difference is that in 1.x, the M2D2 object was mainly a Proxy object which upon change, updated the DOM. However the main issue was that if you changed the DOM directly, there was no way to update the M2D2 object automatically, and thus could have side effects. In 2.x, the M2D2 object is a Node/HTMLElement wrapped around a Proxy and extended, which means that you can safely change the DOM directly without having side effects. Because now the M2D2 object is a DOM element, you have access to everything through vanilla javascript (like classList, appendChild, style, etc), which greatly simplified things.
Developing
To modify or contribute to this code, start by cloning this repository.
Then execute: npm install
To build: npm run build (produces dist/ — ESM, CJS, IIFE, and .d.ts)
To typecheck: npm run typecheck
To run all tests: npm test (Vitest + jsdom, terminal-based)
Acknowledgments:
Developed with IntelliJ Ultimate Edition. I would like to thank JetBrains for their support.
