How to build a JavaScript Framework in [2023]

Facebook logoTwitter logoLinkedin logo
An illustration of a framework

Will learn how to build a simple JavaScript Framework that will help us interact with the DOM (Document Object Module), and Build Interactive UI (User Interface), Using only pure JavaScript to Build the Framework

What is a Framework

A framework is a structured approach or set of guidelines that provides a common structure for developers to build applications. It is a set of pre-written codes that can be used to perform common tasks, solve common problems, or provide a set of tools that simplify the development process.

Frameworks can be thought of as a skeleton or a blueprint for building an application. They provide a structure that developers can use to organize their code, manage dependencies, and enforce best practices. By using a framework, developers can focus on building the unique features of their applications rather than worrying about the underlying infrastructure.

Where frameworks used

Frameworks are commonly used in web development, where they can provide a common structure for building web applications. Examples of popular web frameworks include Ruby on Rails, Django, Laravel, and Angular.

Frameworks can also be used in other areas of software development, such as mobile app development, desktop app development, and game development. In each of these areas, frameworks provide a set of tools and guidelines that make it easier for developers to build high-quality applications.

Let's start building our JavaScript Framework

First, let's create a simple project folder and create 2 files in it index.html sweetui.js, Sweetui will be the name of our framework, This framework will be similar to jQuery and It will make interaction with the DOM easier with its well-constructed and simple API

First Step helper functions

In the top of sweetui.js file will create a function that will help us grab Elments from the DOM

The function is based on the document.querySelector method and it will take 2 parameters the first one is required and it's the selector, The second one is optional and by default is set to true, It its true it will return a List of HTML elements based on the selector if it's false it will return one Element base on the selector if it didn't find any it will return null

// Select Elements from the DOM
function $(selector, selectAll = false) {
    if (selectAll) {
        return document.querySelectorAll(selector);
    }
    return document.querySelector(selector);
}
Copy

How to use it to get Elements from the DOM

// Usages
let buttonEl = $(".btn"); // return a button element
let list = $("ul.list > li", true); // return a list of li elements
Copy

Now we need a help function taht will help us add custom methods on All html Elments

This function will access the HTMLElement interface prototype and it ill add the custom method

The HTMLElement interface represents any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.
function addMethod(name, method) {
    HTMLElement.prototype[name] = method;
}
Copy

Next helper method it will be added to the javascript Object interface It will hep us loop over each key and value in the objec

Object.prototype.each = function (callback) {
    for (let [key, value] of Object.entries(this)) {
        callback(key, value);
    }
};
Copy

Second Step adding custom methods

First on is on The on method whant be much drefrent from addEventLsinter It jus will be a shorter version

And this is how we will be using the addMethod function Will allows returns the this the this keyword represents the current elements that the method is called on, we return this so we can chain multiple methods as in jQuery chain

// Add on method to make adding event easer
addMethod("on", function (event, callback) {
    this.addEventListener(event, callback);
    return this;
});

// Usage
$('div').on('click', (e) => {
    console.log("click event: ", e)
})
Copy

Next on the list is css method th css method will alows us to style an Element like you would in React

// Add inline styles
addMethod("css", function (styles) {
    styles.each((key, value) => {
        this.style[key] = value;
    });
    return this;
});

// Usage
$('div').css({
    color: "red",
    fontSize: "19px",
    width: "200px"
});
Copy

After that will add the attr method attr method will make adding multiple attributes so much easier

// Add attributes to an element
addMethod("attr", function (attributes) {
    attributes.each((key, value) => {
        this.setAttribute(key, value);
    });
    return this;
});

// Usage
$("div").attr({
    id: "div-el",
    tabindex: "-1",
    "data-index": 2,
    class: "bg-red text-lg",
});
Copy

Now we need an easy way to maniplate classs

// handle classes actions
// the class name arg ether will be an array of classes
// Or a string has spaces to separate classes
addMethod("classes", function (action, classNames) {
    let _classes;
    if (typeof classNames === "string") {
        _classes.split(/\s+/g);
    } else if (Array.isArray(classNames)) {
        _classes = classNames;
    }
    _classes.forEach((_cls) => {
        this.classList[action](_cls);
    });
    return this;
});

// Usage
let el = $("div");
// Add class
el.classes("add", "text-lg");
// Toggle class
el.classes("toggle", "active");
// remove class
el.classes("remove", "hidden");
Copy

clone mothod will help us copy an Elementm Read more about cloneNode method

addMethod("clone", function (deep = true) {
    return this.cloneNode(deep);
});
Copy

that last method is insert method, It will help us insert Elments to the DOM with an easy to use API this is how it works

addMethod("insert", function (position, element) {
    let positions = {
        before: "beforebegin",
        after: "afterend",
        append: "beforeend",
        prepend: "afterbegin",
    };
    this.insertAdjacentElement(positions[position], element);
    return this;
});

// Usage
let el = $('div');
let newEl = document.createElement('span');
// insert element before
el.insert("before", newEl);
// It will be inserted after the element
el.insert("after", newEl)
// It will be added as the last child
el.insert('append', newEl)
// It will be added as the first child
el.insert("prepend", newEl);
Copy

Conclusion

I hope you learned something new today, this post was meant to help you create your own javaScript framework and simplify it so you can pick it up on your own and keep adding your own features and improving it.