Episode # 4 - Creating Your First Basic Monorepo: The Node Modules Trick
As a former 3D Animator with more than 12 years of experience, I have always been fascinated by the intersection of technology and creativity. That's why I recently shifted my career towards MERN stack development and software engineering, where I have been serving since 2021.
With my background in 3D animation, I bring a unique perspective to software development, combining creativity and technical expertise to build innovative and visually engaging applications. I have a passion for learning and staying up-to-date with the latest technologies and best practices, and I enjoy collaborating with cross-functional teams to solve complex problems and create seamless user experiences.
In my current role as a MERN stack developer, I have been responsible for developing and implementing web applications using MongoDB, Express, React, and Node.js. I have also gained experience in Agile development methodologies, version control with Git, and cloud-based deployment using platforms like Heroku and AWS.
I am committed to delivering high-quality work that meets the needs of both clients and end-users, and I am always seeking new challenges and opportunities to grow both personally and professionally.
In this lesson, we’ll create a basic monorepo using Node.js module resolution and a clever technique we call the Node Modules Trick. This will allow us to structure and manage multiple modules in one repository effectively.
Step 1: Setting Up the Project
Initial Directory Structure
Start by creating a packages folder, which will contain two subfolders:

moduleA
moduleB
Each module will act as a standalone package, designed to be imported and used in other projects.
monorepo-project/
│
└── packages/
├── moduleA/
│ └── index.js
└── moduleB/
└── index.js
Writing Module Code
Inside
moduleA/index.js:console.log('This is module A');Inside
moduleB/index.js:console.log('This is module B');
Testing Module A
Run moduleA using Node.js:
node packages/moduleA/index.js
Output:
This is module A
Step 2: Importing One Module into Another
Now let’s make moduleA call moduleB.
Modify moduleA/index.js:
console.log('This is module A');
require('../moduleB');
Run moduleA again:
node packages/moduleA/index.js
Output:
This is module A
This is module B
Here, we’re using a relative path (../moduleB) to import moduleB.
Step 3: Requiring Modules by Name
In a real-world scenario, modules should behave like npm packages and be referenced by their name, not relative paths. To do this:
Open
moduleB/index.jsand update the name:console.log('This is module B');Open
moduleA/index.jsand modify therequirestatement:console.log('This is module A'); require('moduleB');Now run
moduleA:node packages/moduleA/index.js
Expected Output:
This is module A
This is module B
Actual Output:
Error: Cannot find module 'moduleB'
Why the Error Occurs
Node.js uses a module resolution strategy where it looks for the node_modules folder to resolve packages. In this case, it:
Looks for a
node_modulesfolder insidepackages/moduleA.If not found, moves to the parent directories, searching for
node_modules.Since no
node_modulesfolder exists, it fails to locate moduleB.
Step 4: The Node Modules Trick
To make Node treat the packages folder as if it were the node_modules folder:
Rename the
packagesfolder tonode_modules.monorepo-project/ │ └── node_modules/ ├── moduleA/ │ └── index.js └── moduleB/ └── index.jsRun
moduleAagain:node node_modules/moduleA/index.js
Output:
This is module A
This is module B
How This Trick Works
By renaming packages to node_modules:
Node.js treats moduleA and moduleB as if they were installed npm packages.
The
require('moduleB')statement now works because Node resolves the module from the renamednode_modulesfolder.
Limitations of the Node Modules Trick
While effective for small projects:
It creates a non-intuitive directory structure.
Doesn’t scale well as the project grows.
Next Steps
In the upcoming lessons, we’ll:
Explore advanced tools and strategies to manage monorepos.
Learn how to use Yarn Workspaces to simplify and professionalize your setup.
This foundational understanding will prepare you to work with more powerful tools for scalable monorepo development! 🚀