Every developer faces a hard choice when building a website. You need to pick a frontend tool to manage your user interface. Recently, I looked at the current options for my new project, Vlox, and I felt completely stuck. Nothing fit my exact needs.
- jQuery? Too old. It was great years ago, but it doesn't fit modern JavaScript development patterns.
- Modern Frameworks? Too complex and heavy. They require massive build tools and endless configuration just to render a simple webpage.
- Vanilla JS? Too verbose. Writing pure JavaScript is perfectly lightweight, but writing
document.querySelectorand managing event listeners manually takes too many lines of code. It quickly gets messy.
I wanted something different. I wanted a tool that was fast, small, and clean—something to keep Vlox incredibly lightweight. To challenge myself, I decided to engineer my own solution: NanoScript.
Under the Hood: How NanoScript Works
1. The Master Toolbox Architecture
To make NanoScript incredibly fast, I had to solve a core library design problem. I didn't want to force developers to type the new keyword every single time they called the NS() function just to spin up an instance. At the same time, I refused to attach methods directly to every single instance, which duplicates memory and ruins performance in large-scale apps.
To solve this, I adopted the brilliant architecture originally made by jQuery. Everything depends on this single line of code:
NS.prototype.init.prototype = NS.prototype;
Here is exactly how it works under the hood:
- The Selector Engine (
init): Theinitfunction acts as a lightweight selector engine. Its only job is to find and target DOM elements. -
Accessing Elements: Right now, you target the underlying elements array, though I am working on an update to make this access direct and cleaner.
// Current syntax: const firstEl = NS(".box").elements[0]; // Upcoming syntax: const firstEl = NS(".box")[0]; The Shared Prototype: The main function’s prototype (
NS.prototype) holds all the core library methods. By pointing the selector engine's prototype back toNS.prototype, we attach those methods to memory exactly once.
Think of it like a master toolbox. Instead of handing a heavy, duplicate set of tools to every single instance created, the instances simply look back at the master toolbox whenever they need a tool. This saves massive amounts of memory and keeps execution fast.
2. Max Performance Wrapper
It's essentially a smart wrapper around the features already built into your browser. Instead of inventing a heavy custom engine, it uses native browser powers like querySelectorAll and modern browser APIs. Because it doesn't add heavy code or complex virtual DOMs, your code runs at top speed with zero overhead. Perfecto! 👌🏻
3. The Selector Engine
NanoScript's selector engine is pretty straightforward. It accepts string selectors, NodeLists, HTMLCollections, and native Element instances. If you pass an invalid selector string, it throws a TypeError stating that the given selector is invalid. I added this check because I hate debugging app failures caused by simple typo errors 😅. Also, if you pass any other data type, or if no matching elements are found, the engine returns an empty array—just like jQuery.
Mini Comparison:
Let's compare NanoScript and vanilla JavaScript for a common task: selecting multiple buttons and toggling a class on click.
Using Vanilla JS:
document.querySelectorAll(".btn").forEach(button => {
button.addEventListener("click", function () {
button.style.color = "blue";
});
});
Using NanoScript:
NS(".btn").on("click", function () {
this.style.color = "blue";
// OR: NS(this).css("color", "blue");
});
NanoScript gives you clean syntax of without the weight of a massive framework.
What Is Missing Right Now?
NanoScript is still growing guys. There are a few features that I'm planning to add:
- A Fetch Wrapper: Right now, there is no built-in way to handle API calls easily. I want to add a simple network helper to fetch data without writing long native
fetchblocks or importing separate libraries like Axios. - Traversal Methods: Built-in ways to easily navigate the DOM—such as finding a parent, the next sibling, or the closest matching element—are not implemented yet.
I'm also planning to write the docs very soon!
Try Out NanoScript!
I would love to get your feedback on NanoScript. Can you try it out for your next small project or prototype? You can inspect the source code, check out the implementation, and star the repository at https://github.com/Hfs2024/NanoScript.
See how it feels compared to vanilla JavaScript. Let me know what you think and what features you want next!
Top comments (0)