Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A dynamic programming language used in all sorts of web and mobile applications.
A cross-platform programming language designed to run robust applications on any device.
A UI toolkit used to build natively compiled applications from a single codebase.
A functional programming language that’s ideal for scalability, maintainability, and reliability.
A Customer Relationship Management (CRM) platform that seamlessly integrates with your business operations.
A high-performance programming language that makes it easy to build simple, reliable, and efficient software.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
Monorepo solutions provide a scalable architecture and tooling configuration for complex projects. If you have ever needed to deploy a Node application and publish npm packages that are related, try a modern approach with Rush.
This article will cover monorepos that maintain Node.js-based projects. A monorepo is a single repository that manages multiple projects. Google, Facebook, and Microsoft (the founder of this article’s proposed solution) have taken the leap toward monorepo architecture to battle massive code and commit volume. These projects can be isolated components or utilities that are published to package repositories or full-blown framework-based projects like Next.js, Vue, and Angular applications.
The traditional multirepo model, where multiple VCS repositories are used to maintain isolated codebases, often starts as a simple solution. This approach can quickly become cumbersome to work with as codebases grow in size and complexity or as the number of code repositories becomes unmanageable. This is where a monorepo solution would excel.
Consider the case where a development team is working on a single web application, but they now need to share code for consumption by another team. These might be core utilities or even smart components. The team successfully factors code into a separate repository, complete with a CI/CD system that can publish packages. PR reviews are now split across repositories. A developer working on the main web application now needs to wait for a new package to be published so that they can use their own library in the next web release. This problem is compounded as the number of these repositories grows.
In a monorepo solution,
We’ve all worked on projects that have tightly coupled, monolithically architectured implementations. One major benefit of a monorepo solution is that it can provide a healthy starting point for modularizing your application.
Is there a well-designed component styling solution for your React application from which other teams could benefit? Would having the styling factored out make styling changes easier by isolating its code in a single package? Factor out your styling into a package. Do you have a linting configuration that could be propagated throughout your organization? Do you maintain an analytics implementation that could be consumed by multiple third parties?
When the proper tooling is in place, monorepos make it easy to start publishing packages that would otherwise require heavy lifting to coordinate into a separate repository and configure CI/CD processes. When designed properly, publishing a new package for the first time can be as easy as setting ”shouldPublish”: false to ”shouldPublish”: true.
Internal utilities or implementations are commonly duplicated across different projects and repositories, especially when a packaging solution is not immediately available. A monorepo approach makes it possible to factor these into shared packages without the need to publish and bump these references down a long chain of dependencies. In particular, Rush can make use of a variety of versioning policies to ease the strain of cascading version bumps.
A transitive dependency is any dependency in the dependency tree that is pulled in by direct dependencies and is not specified as a direct dependency in a project’s package.json. When our Node applications grow, it is not uncommon to see transitive dependencies in the order of thousands. Install times can be reduced by caching shared dependencies across all monorepos. By virtue of PNPM or Yarn workspaces, Rush can:
Rush, a monorepo solution created by the platform team for Microsoft SharePoint, enters the conversation as a relatively underutilized solution when it comes to monorepo management. Tools such as Lerna have become mainstream, but there are growing concerns around its longevity as a project, given that a single developer has been contributing most of its code over the last three years. Consumers have been wondering if PNPM support will be introduced since 2018! It may not be introduced soon, given the project’s health, even though it has well-documented speed improvements over NPM and Yarn.
Web developers and architects alike enjoy having options when it comes to any solution. Package management is no different in this regard—the three most popular package managers today are:
Rush supports each of these agnostically, although each package manager’s performance impacts Rush itself. Yarn and PNPM work especially well with Rush because they both support workspaces, which allows the package manager to install and collect dependencies for all projects in a single pass. PNPM is a particularly interesting option with Rush, as it provides extra safety around phantom dependencies and the NPM doppelgangers issue.
Different transpilation, linting, and bundling tools (Typescript, ESLint, Webpack, Rollup, etc.) often have their own caching layer to reduce incremental build times. Rush takes this a step further with their own build caching solution.
With build caching, Rush will create a tarball of each project’s build output. When subsequent builds occur, Rush can restore this build output instead of rebuilding the project, skipping the overhead that a no-op incremental build would have incurred.
This feature becomes especially powerful when combined with remote storage integration. Rush can leverage an Amazon S3 or Azure blob storage container to cache builds across any machine with the appropriate credentials. In such a configuration, developers would be able to pull PRs or branches that were built by CI and run code with practically zero build time.
Note that build caching with Rush is experimental as of the time of writing.
When working with many dependencies spread across multiple projects, it can be helpful to ensure that only one version of a package is in use within any given project, which implies the following:
Rush can enforce consistent versioning when performing dependency installations or additions.
With Rush, it becomes easy to communicate and track changes across publishable packages. When publishable packages undergo source file changes on a branch separate from the main branch, they are flagged by the rush change --verify command. This instructs the developer to run rush change, if they haven’t already, and for each modified package this utility guides them through:
This is easily integrated into a PR trigger to ensure that no changes go undocumented. When the next package is triggered, each project gets an up-to-date CHANGELOG.md file which compiles a listing of tracked changes.
Rush has an active Zulip chat room where questions and concerns that may not be covered in documentation or GitHub issues can be addressed often more quickly than one may expect of other monorepo tooling teams.
Following from a minimal Rush example provided by the Rush Stack team, a standard directory structure may look as such:
│── apps
│ └── my-app
│ ├── package.json
│ └── src
│── common
│ │── config
│ │ └── rush
│ │── git-hooks
│ │ └── commit-msg.sample
│ │── scripts
│ └── ...
│── libraries
│ └── my-controls
│ ├── lib
│ ├── package.json
│ └── src
├── LICENSE
├── README.md
├── rush.json
└── tools
└── my-toolchain
├── package.json
└── src
This directory structure separates concerns in a comfortable manner. Note that each project within the monorepo has a familiar structure as well: src for source code, a package.json for specifying dependencies, and potentially a lib directory for build outputs.
Once configured, moving an existing web application into a Rush directory structure may be as simple as dropping tracked files into apps/<name-of-your-app>. From there, you can consider what is useful to share or reuse as the monorepo grows and you begin populating the libraries directory.
Monorepo solutions serve as a step toward a more collaborative development experience. Code reuse becomes easy. Dependency management is safer. This shouldn’t be the default for all Node projects (especially smaller ones), but if you need it, it’s a lifesaver.
From the rush --help command itself:
Rush makes life easier for JavaScript developers who develop, build and publish many packages from a central Git repo. It is designed to handle very large repositories supporting many projects and people. Rush provides policies, protections, and customizations that help coordinate teams and safely onboard new contributors. Rush also generates changelogs and automates package publishing. It can manage decoupled subsets of projects with different release and versioning strategies. A full API is included to facilitate integration with other automation tools. If you are looking for a proven turnkey solution for monorepo management, Rush is for you.
If you’re interested in learning how a monorepo solution could improve your team’s workflow, read the Rush Stack documentation for more information. They have guides geared towards developers and repository maintainers.
We’d love to learn more about your project.
Engagements start at $75,000.