DEV Community

Cover image for React is bloated, but Vanilla isn't the only solution.

React is bloated, but Vanilla isn't the only solution.

rwbeast profile image rwbeast Updated on ・2 min read

React is bloated, but going complete Vanilla JS can make your app really difficult to maintain and it severally impacts the DX (Developer Experience).
Just think about writing document.querySelector('...') everytime you want to fetch an element from the dom or writing $element.addEventListener(...) everytime you want to attach an event to an element.

I am not an anti-vanillaJS or anti-framework guy but trust me there's a mid-way! that is using a tiny toolkit which acts as a very thin superficial layer over the Vanilla JS ( toppings?? ) but still not something as bloated as a library or a framework. Just imagine if you could replace all those querySelector(...) calls with qs(...) or qsa(...) for querySelectorAll or those addEventListener(...) calls with some JQuery-like on(...) and off(...) functions just by adding a tiny toolkit at the top of your app.js file.

I know that a lot of you already use some sort of Javascript toolkits you made for personal use and have even used in client projects but a lot of newcomers think you either have to go completely the framework way or you have to completely go the vanilla js way. but it's a wrong thinking.

To prove my point I am gonna show you the tiny toolkit that I use in my projects, it's called tez.js ( tez means fast in Hindi ).

/* tez.js | Created By Harsh Singh | MIT License */

const doc = document;

export const qs = (sel, ctx = doc) => ctx.querySelector(sel);

export const qsa = (sel, ctx = doc) => ctx.querySelectorAll(sel);

export const style = (el, obj) => Object.assign(, obj);

export const attr = (el, name, val) => {

  if(val) {

    return el.setAttribute(name, val);


  return el.getAttribute(name);


export const on = (el, evt, hand) => el.addEventListener(evt, hand, false);

export const off = (el, evt, hand) => el.removeEventListener(evt, hand, false);

export const ready = hand => {

  if (/complete|loaded|interactive/.test(doc.readyState) && doc.body) {

    setTimeout(hand, 1);

  } else {

    on(doc, 'DOMContentLoaded', hand);


Enter fullscreen mode Exit fullscreen mode

this tiny javascript toolkit will save you from the pain of going complete vanilla-js way but will also save you from using a framework.

here's a tiny counter app i made with this toolkit.

<div id="counter"></div>

<button id="inc">+</button>
<button id="dec">-</button>

<script type="module" src="/app.js"></script>
Enter fullscreen mode Exit fullscreen mode
import { ready, qs, on } from '/tez.js'; 

const initApp = () => {

  const counterEl = qs('#counter'),
        incBtn = qs('#inc'),
        decBtn = qs('#dec');

  let count = 0; // initial state

  const updateCounter = v => counterEl.textContent = v;


  on(incBtn, 'click', () => updateCounter(++count));

  on(decBtn, 'click', () => updateCounter(
    count === 0 
      ? 0 
      : --count


ready(initApp); // initializes the app when the dom is ready.
Enter fullscreen mode Exit fullscreen mode

you can clearly see that even a tiny toolkit can improve your DX drastically without costing your app the performance benefits of vanilla js.

JaiHind #JaiShreeRam

Discussion (0)

Editor guide