DEV Community

Yash Hadade
Yash Hadade

Posted on

I Built My First npm Package — A CLI for Scaffolding Modular Node.js Projects

The problem I kept running into
Every time I started a new Node.js backend — whether it was a microservice at realX or a weekend project — I found myself doing the same ritual:

Create the folder structure manually
Copy-paste the same boilerplate files
Wire up the same entry points, route structure, and config setup
Then finally get to actually writing the thing I wanted to build

It wasn't painful enough to complain about loudly, but it was persistent. And persistence is what eventually makes you do something about it.
At work I own a scalable custodian backend — a system with a lot of moving parts that had to stay cleanly separated. Modules for blockchain workers, modules for custody logic, modules for event handling. Over time I developed a personal pattern for how I like to structure these things. A certain way of thinking about separation of concerns that felt natural and repeatable.
That pattern is what became moduler-framework.

What it is
moduler-framework is a CLI tool that scaffolds modular Node.js project structures so you can skip the setup ceremony and get straight to writing logic.

bash

npm install -g moduler-framework
Run the CLI and it generates a clean, opinionated folder structure built around isolated modules — each with its own scope, entry point, and wiring — so your codebase stays organized even as it grows.

The idea is simple: structure shouldn't be an afterthought. When you scaffold it right at the start, you get a codebase that's easier to reason about, easier to test, and much easier for another developer (or future you) to navigate.

Why a CLI specifically
I thought about making it a runtime library — something you'd import. But the real value isn't in what happens at runtime, it's in what happens at the start of a project.

A CLI felt more honest. You run it once, it gives you a foundation, and then it gets out of your way. There's no new dependency sitting in your node_modules forever. The generated code is yours.

Shipping it
Publishing to npm for the first time was both anti-climactic and quietly exciting. Anti-climactic because once you have a package.json and an account, it's just one command. Exciting because you realize: this is public now. Anyone can install this.
I had to think more carefully about:

Naming — moduler-framework is distinct enough to not clash, while still being searchable
Versioning — committing to semver and Conventional Commits from day one to keep the changelog clean
CI — setting up GitHub Actions with commitlint so version bumps stay disciplined

The commitlint setup tripped me up more than I expected. Getting the CI to not fail on PR titles, fixing rebase history, understanding the difference between feat: and chore: in a way that actually maps to meaningful version bumps — all of that was a learning curve I didn't anticipate when I thought of this as "just a small tool."

What I'd tell myself before starting
Write the README before the code. Seriously. If you can't explain what your tool does in three sentences, you don't know what you're building yet.
Keep the scope small and ship it. I had ideas for more features — interactive prompts, custom templates, a config file system. I cut all of it for v1. Ship the thing that solves the core problem. Everything else is v2.
Conventional Commits pay off immediately. Once you have them, your git log becomes documentation. Don't skip this.

Try it out
bash

npm install -g moduler-framework

GitHub: https://github.com/yashhadade/moduler-framework
npm: https://www.npmjs.com/package/moduler-framework?activeTab=readme

If you've been doing the same folder setup ritual on every new project, maybe this saves you some time. And if you have feedback — issues, PRs, or even just telling me it doesn't work the way you expected — I'm genuinely interested.

This is my first published npm package. Building it was part real utility, part curiosity about what shipping open-source actually involves. Turns out it involves a surprising amount of commitlint debugging.

Top comments (0)