Oops! Something went wrong while submitting the form.
We use cookies to improve your browsing experience on our website, to show you personalised content and to analize our website traffic. By browsing our website, you consent to our use of cookies. Read privacy policy.
Beginnings are often messy. Be it in any IT project, we often see that at a certain point, people look forward to revamping things. With revamping, there comes additional costs and additional time. And those will be a lot costlier if not addressed at the right time to meet the customers’ feature demands. Most things like code organization, reusability, code cleanup, documentation are often left unattended at the beginning only to realize that they hold the key to faster development and ensure quick delivery of requested features in the future, as projects grow into platforms to serve huge numbers of users.
We are going to look at how to write a scalable frontend platform with React and Lerna within an hour in this blog post. The goal is to have an organized modular architecture that makes it easy to maintain existing products and can quickly deliver new modules as they arrive.
Going Mono-Repo:
Most projects start with a single git/bitbucket repository and end up in chaos with time. With mono-repo, we can make it more manageable. That being said, we will use Lerna, npm and YARN to initialize our monorepo.
Let's go through the files generated with it. So we have the following files:
- package.json
- lerna.json
- packages/
package.json is the same as any other npm package.json file. It specifies the name of the project and some basic stuff that we normally define like adding husky for pre-commit hooks.
lerna.json is a configuration file for configuring Lerna. You can find more about Lerna configuration and supported options at Lerna concepts.
packages/ is a directory where all our modules will be defined and Lerna will take care of referencing them in each other. Lerna will simply create symlinks of referenced local modules to make it available for other modules to use.
For better performance, we will go with YARN. So how do we configure YARN with Lerna?
It's pretty simple as shown below.
We just need to add “npmClient”: “yarn” to lerna.json
Using YARN workspaces with Lerna
YARN workspace is a quick way to get around the mess of `yarn link` i.e. referencing one module into another. Lerna already provides it so why go with YARN workspaces?
The answer is excellent bootstrapping time provided by YARN workspaces.
This will take care of linking different modules in a UI platform which are mentioned in the packages folder.
Once this is done, we can proceed to bootstrap, which in other terms, means forcefully telling Lerna to link the packages. As of now, we do not have anything under it, but we can run it to check if this setup can bootstrap and work properly.
So it's all about the Lerna and YARN set up, but how should one really organize a UI package to build in a manageable and modular way.
What most React projects are made of
1 - Component Libraries 2 - Modules 3 - Utils libraries 4 - Abstractions over React-Redux ( Optional but most organizations go with it)
Components: Most organizations end up building their own component libraries and it is crucial to have it separated from the codebase for reusability of components. There exist a lot of libraries, but when you start building the product, you realize every library has something and misses something. Most commonly available libraries convey a standard UX design pattern. What if your designs don’t fit into those at a later point? So we need a separate components library where we can maintain organization-specific components.
Modules: At first you may have one module or product, but over time it will grow. To avoid breaking existing modules over time and keeping change lists smaller and limited to individual products, it's essential to split a monolith into multiple modules to manage the chaos of each module within it without impacting other stable modules.
Utils: These are common to any project. Almost every one of us ends up creating utils folders in projects to help with little functions like converting currency or converting large numbers like 100000 as 100K and many more. Most of these functions are common and specific to organizations. E.g. a company working with statistics is going to have a helper function to convert large numbers into human-readable figures and eventually they end up copying the same code. Keeping utils separated gives us a unique opportunity to avoid code duplication of such cases and keep consistency across different modules.
Abstractions over React-Redux: A lot of organizations prefer to do it. AWS, Microsoft Outlook, and many more have already adopted this strategy to abstract React & Redux bindings to create their own simplified functions to quickly bootstrap a new module/product into an existing ecosystem. This helps in faster delivery of new modules since developers don’t get into the same problems of bootstrapping and can focus on product problems rather than setting up the environment.
One of the most simplified approaches is presented at react-redux-patch to reduce boilerplate. We will not go into depth in this article since it's a vast topic and a lot of people have their opinion on how this should be built.
Example:
We will use create-react-app & create-react-library to create a base for our libraries and modules.
It will try to publish the packages that have been changed since the last commit.
Summary:
With the use of Lerna and YARN, we can create an efficient front-end architecture to quickly deliver new features with less impact on existing modules. Of course with additional bootstrapping tools like yeoman generator along with abstractions over React and Redux, it makes the process of introducing to new modules a piece of a cake. Over time, you can easily split these modules and components into individual repositories by utilizing the private npm repositories. But for the initial chaos of getting things working and quick prototyping of your next big company’s UI architecture, Lerna and YARN are perfectly suited tools!!!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Building Scalable Front-end With Lerna, YARN And React In 60 Minutes
Beginnings are often messy. Be it in any IT project, we often see that at a certain point, people look forward to revamping things. With revamping, there comes additional costs and additional time. And those will be a lot costlier if not addressed at the right time to meet the customers’ feature demands. Most things like code organization, reusability, code cleanup, documentation are often left unattended at the beginning only to realize that they hold the key to faster development and ensure quick delivery of requested features in the future, as projects grow into platforms to serve huge numbers of users.
We are going to look at how to write a scalable frontend platform with React and Lerna within an hour in this blog post. The goal is to have an organized modular architecture that makes it easy to maintain existing products and can quickly deliver new modules as they arrive.
Going Mono-Repo:
Most projects start with a single git/bitbucket repository and end up in chaos with time. With mono-repo, we can make it more manageable. That being said, we will use Lerna, npm and YARN to initialize our monorepo.
Let's go through the files generated with it. So we have the following files:
- package.json
- lerna.json
- packages/
package.json is the same as any other npm package.json file. It specifies the name of the project and some basic stuff that we normally define like adding husky for pre-commit hooks.
lerna.json is a configuration file for configuring Lerna. You can find more about Lerna configuration and supported options at Lerna concepts.
packages/ is a directory where all our modules will be defined and Lerna will take care of referencing them in each other. Lerna will simply create symlinks of referenced local modules to make it available for other modules to use.
For better performance, we will go with YARN. So how do we configure YARN with Lerna?
It's pretty simple as shown below.
We just need to add “npmClient”: “yarn” to lerna.json
Using YARN workspaces with Lerna
YARN workspace is a quick way to get around the mess of `yarn link` i.e. referencing one module into another. Lerna already provides it so why go with YARN workspaces?
The answer is excellent bootstrapping time provided by YARN workspaces.
This will take care of linking different modules in a UI platform which are mentioned in the packages folder.
Once this is done, we can proceed to bootstrap, which in other terms, means forcefully telling Lerna to link the packages. As of now, we do not have anything under it, but we can run it to check if this setup can bootstrap and work properly.
So it's all about the Lerna and YARN set up, but how should one really organize a UI package to build in a manageable and modular way.
What most React projects are made of
1 - Component Libraries 2 - Modules 3 - Utils libraries 4 - Abstractions over React-Redux ( Optional but most organizations go with it)
Components: Most organizations end up building their own component libraries and it is crucial to have it separated from the codebase for reusability of components. There exist a lot of libraries, but when you start building the product, you realize every library has something and misses something. Most commonly available libraries convey a standard UX design pattern. What if your designs don’t fit into those at a later point? So we need a separate components library where we can maintain organization-specific components.
Modules: At first you may have one module or product, but over time it will grow. To avoid breaking existing modules over time and keeping change lists smaller and limited to individual products, it's essential to split a monolith into multiple modules to manage the chaos of each module within it without impacting other stable modules.
Utils: These are common to any project. Almost every one of us ends up creating utils folders in projects to help with little functions like converting currency or converting large numbers like 100000 as 100K and many more. Most of these functions are common and specific to organizations. E.g. a company working with statistics is going to have a helper function to convert large numbers into human-readable figures and eventually they end up copying the same code. Keeping utils separated gives us a unique opportunity to avoid code duplication of such cases and keep consistency across different modules.
Abstractions over React-Redux: A lot of organizations prefer to do it. AWS, Microsoft Outlook, and many more have already adopted this strategy to abstract React & Redux bindings to create their own simplified functions to quickly bootstrap a new module/product into an existing ecosystem. This helps in faster delivery of new modules since developers don’t get into the same problems of bootstrapping and can focus on product problems rather than setting up the environment.
One of the most simplified approaches is presented at react-redux-patch to reduce boilerplate. We will not go into depth in this article since it's a vast topic and a lot of people have their opinion on how this should be built.
Example:
We will use create-react-app & create-react-library to create a base for our libraries and modules.
It will try to publish the packages that have been changed since the last commit.
Summary:
With the use of Lerna and YARN, we can create an efficient front-end architecture to quickly deliver new features with less impact on existing modules. Of course with additional bootstrapping tools like yeoman generator along with abstractions over React and Redux, it makes the process of introducing to new modules a piece of a cake. Over time, you can easily split these modules and components into individual repositories by utilizing the private npm repositories. But for the initial chaos of getting things working and quick prototyping of your next big company’s UI architecture, Lerna and YARN are perfectly suited tools!!!
Velotio Technologies is an outsourced software product development partner for top technology startups and enterprises. We partner with companies to design, develop, and scale their products. Our work has been featured on TechCrunch, Product Hunt and more.
We have partnered with our customers to built 90+ transformational products in areas of edge computing, customer data platforms, exascale storage, cloud-native platforms, chatbots, clinical trials, healthcare and investment banking.
Since our founding in 2016, our team has completed more than 90 projects with 220+ employees across the following areas:
Building web/mobile applications
Architecting Cloud infrastructure and Data analytics platforms