Introduction to Mithril.js: A Lightweight JavaScript Framework
Why Start Writing About Mithril.js?
As a software developer, I’ve spent a considerable amount of time exploring various JavaScript frameworks and libraries. After working with several of them, I found Mithril.js to be particularly interesting due to its simplicity and efficiency. This blog aims to share my insights, experiences, and practical tips on working with Mithril.js.
What Is Mithril.js?
Mithril.js is a modern client-side JavaScript framework used for building Single Page Applications (SPAs). It is known for its small size (~8kb gzipped), fast performance, and straightforward API. Unlike some larger frameworks, Mithril.js focuses on doing the essentials with minimal overhead, making it an excellent choice for developers who value simplicity and speed.
Getting Started with Mithril.js
Preparation
You can quickly get started with Mithril.js by installing it via npm:
# install mithril and ts type definition
npm install mithril --save
npm install @types/mithril --save-dev
# install webpack to build the source code
npm install webpack webpack-cli --save-dev
# install http-server
npm install http-server --save-dev
Create webpack.config.js file.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
},
mode: 'development'
};
Add a “dev” entry to the scripts section in package.json:
{
"dev": "webpack && http-server"
}
Let’s create a index.html file to follow along:
<html>
<head>
<title>Hello world</title>
</head>
<body>
<script src="dist/main.js"></script>
</body>
</html>
Basic Example
Here is a simple example to demonstrate how easy it is to create a component and render it using Mithril.js:
// src/index.js
import m from 'mithril';
/**
* Create a component.
* A Mithril.js component is just an object with a view function.
*/
const HelloComponent = {
view: () => {
return m("div", "Hello World!");
}
};
// Mount the component to a DOM element
m.mount(document.body, HelloComponent);
Component Lifecycle Methods
Components have liftcycle methods, which are called at various points during the lifetime of a DOM element.
oninit
This is called before its DOM element is attached to the document and is guaranteed to run on parent vnodes before children vnode.
⚠️ Warning
You should never access the vnode.dom from the init method.
oncreate
This is called after a DOM element is created and attached to the document.
onbeforeupdate
This is called before a DOM element update, if this method return false, the vnode don’t update.
onupdate
This is called after a DOM element is updated.
onbeforeremove
This is called before a DOM element is detached from the document.
onremove
This is called before a DOM element is removed from the document.
Routing Example
Mithril.js makes it easy to set up routing for your application. Here is an example of how to define routes and components:
// src/index.js
import m from 'mithril';
// Define Home component
const Home = {
view: () => {
return m("div", "Welcome to the Home Page");
}
};
// Define About component
const About = {
view: () => {
return m("div", "About Us");
}
};
// Configure routes
m.route(document.body, "/", {
"/": Home,
"/about": About
});
Example: User Management Dashboard
Let’s create a more complex example by building a User Management Dashboard. This example will include multiple components, routing, and state management.
Step 1: Define the User Model
We’ll create a model to manage our user data:
// src/index.js
const User = {
list: [],
loadList: function() {
return m.request({
method: "GET",
url: "https://jsonplaceholder.typicode.com/users",
})
.then(function(result) {
User.list = result;
});
},
current: {},
load: function(id) {
return m.request({
method: "GET",
url: "https://jsonplaceholder.typicode.com/users/" + id,
})
.then(function(result) {
User.current = result;
});
}
};
Step 2: Create the UserList Component
This component will display a list of users:
// src/index.js
const UserList = {
oninit: User.loadList,
view: function() {
return m("div", [
m("h1", "User List"),
m("ul", User.list.map(function(user) {
return m("li", m(m.route.Link, { href: "/user/" + user.id }, user.name));
}))
]);
}
};
Step 3: Create the UserDetail Component
This component will display the details of a selected user:
// src/index.js
const UserDetail = {
oninit: function(vnode) { User.load(vnode.attrs.id) },
view: function() {
return m("div", [
m("h1", User.current.name),
m("p", "Email: " + User.current.email),
m("p", "Phone: " + User.current.phone),
m("button", { onclick: () => m.route.set("/users") }, "Back to list")
]);
}
};
Step 4: Configure Routing
We will configure the routes for our application:
// src/index.js
m.route(document.body, "/users", {
"/users": UserList,
"/user/:id": UserDetail
});
Conclusion
Mithril.js is a powerful yet lightweight framework that offers simplicity and efficiency for building Single Page Applications. Whether you are looking for a new framework to experiment with or seeking a performance-oriented solution for your next project, Mithril.js is worth considering.