In this article series, I’ll share how monolithic JavaScript (and TypeScript) applications can be split into distributed (micro)services with just configuration. We’ll explore the technical mechanics of this transformation and the principles for designing applications that embrace this duality.
The runtime we’ll be dissecting is Jitar. It’s fully open source, and you’ll find a link to the GitHub repository at the bottom of this article.
Part II — Splitting Applications
In the previous part, we discussed the motivation, design goals, and technology choices of our runtime. In this part, we’ll dive deeper into the mechanics of splitting applications into distributable bundles.
Writing Distributable Monoliths
A well-structured modular monolith is essentially the non-distributed version of microservices. The most fundamental requirement is having clearly defined boundaries. The key question: what are these boundaries and how do we define them?
Example: Business Process for Generating Monthly Sales Reports
- Each function is placed in its own module file, grouped by domain concept
- Functions must be asynchronous and stateless for remote calls
Splitting the Monolith
- Replace internal function calls with remote ones for distributed parts
- Use JavaScript module system for scalable solutions
- Use configuration (e.g., JSON) to define distribution plan and access levels
Rewiring an Application
- Replace internal imports with remote procedure calls for other segments
- Use drop-in replacement functions for remote calls
- Use dynamic imports for shared resource modules
Generating Distributable Bundles
- Create segment-specific modules that re-export public/protected entries
- Use bundlers (Webpack, Rollup, Turbopack) to produce deployable packages
- Integrate configuration and versioning into segment bundles
This approach enables efficient, distributable JavaScript applications. For more details and code, see the Jitar project on GitHub: https://github.com/MaskingTechnology/jitar
Thanks for reading!