Creating a web3 DApp with a NX Monorepo

Apperside - Aug 2 - - Dev Community

This is a story about how I turned this, this, this and this projects into this NX monorepo containing a full web3 Dapp.

At the end of the story we'll turn this process into a web3 dapp starter kit repository.

I will not drill down to the details of the code, as it is not the focus of this series (and actually needs to be strongly refactored), rather than I want to highlight the main challenges and the problems I encountered (and how I solved them ), and the approach I used to quickly make this migration starting from a never seen before codebases and without any web3 development knowledge.

Let’s start by giving a little bit of context:

A friend of mine asked me to help him with an opensource web3 project, called Baluni, he is working on. This project helps balancing assets in your portfolio, but talking about this is not in the article's scope.

He his a brillant solidity developer with quite good programming skills, but he does not identify him self as a professional developer (he is a musician actually) even though he can code much better than a lot of people that identify them self as professional developers 😁.

He asked me to join the project to help him giving a more professional and maintainable structure to the project that, at that moment, was actually quite bad structured as it consisted of the following distinct projects:

  • BALUNI CORE (link): It is the project that contains the core functionalities plus it has been somehow configured to run as a kind of cli, we'll see it later.
  • BALUNI CONTRACTS (link) and BALUNI HYPERVISOR CONTRACTS (link): These 2 projects are the projects with the core smart contracts and they must be consumed by other projects in the form of an npm library
  • BALUNI UI (link): this project is a monorepo itself, and it contains an ExpressJs server and a NextJS app

I hadn't any doubt about the fact that a monorepo was absolutely needed here, and either I hadn't any doubt about the tool to use: NX.
I used it in the past for small projects, but I was really impressed of it, so I was excited to use it for this job.

Even if, as I said, I don't have any knowledge about web3 development, I was able to analyze the projects, understand their dependencies and the relationships between the project. I planned the migration to be implemented as a monorepo with the following projects:

  • baluni-contracts: library with contracts
  • baluni-hypervisor-contracts: library with contracts
  • baluni-core: core functionalities extracted from baluni project
  • baluni-cli: the cli was badly inglobated in the core, I'll make a dedicated project for it
  • baluni-web: extracted from baluni-ui monorepo
  • baluni-backend: extracted from baluni-ui monorepo

So basically the idea is the following:

  • Make a library out of the projects containing the contracts
  • Make the baluni-core library which will use the contracts libraries (and exposes them)
  • Make the baluni CLI application which uses baluni-core
  • Make the baluni backend which uses baluni-core
  • Make the baluni web app which uses baluni-core and baluni-backend

So, stop talking and let's make our hands dirty.

CREATING THE MONOREPO

Before all, I started a blank NX project following their guidelines, so I just executed the following command:

npx create-nx-workspace
Enter fullscreen mode Exit fullscreen mode

It started an interactive cli asking me about some preferences, like this

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7crud57f5u2t7rp9rhb.png

I choose to don’t use any preset as I want to start as clean as possible and and project one by one and keep track of the process. Let's go ahead

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5dwmruxtggkxfe810n9t.png

At this point I choose the first one.

For the curious ones, this is the difference between these options (taken from their docs):

  • Standalone Application - A repository with a single application
  • Package-Based Repository - A repository with multiple projects that depend on each other via package.json and often have nested node_modules
  • Integrated Repository - A repository with multiple projects that depend on each other via typescript imports and often employ a single version policy

I choose the first option because my app is not a stand alone one and I didn’t want to enter the “single version policy” world at this stage.

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96jxkn7ijcelqrzoi48k.png

Here I went straight and choose to do it later as I don’t want to care about it for now

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s64bjga1mgiefhc3m5r4.png

They try to onboard you to their cloud services, I don’t care now about it, maybe I will write a dedicated article about it

At this point NX will work a bit and will download and setup the project.

As I didn’t selected any preset it was quite quick, but if you choose a preset it will need to download and install all the related dependencies.

Ok, now the project is created

https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7top2jpqll6eadfafgz.png

Since we have chose to start with a blank project, tt contains a bare bone application with nothing much to talk about.

Things will get interesting along the way and you will discover the power of NX when we'll start adding projects.

Along the way, we'll see nice things about NX, like

  • how to create typescript libraries with NX and how to make them publishable on npm
  • how to add custom assets to libraries
  • how to avoid hoisting dependencies for a single project
  • how to generate a package.json in the build output with the used dependencies used by the package
  • how to create and easily run a CLI application inside an nx monorepo

and many more things.

This serie or article will follow with the following articles:

  • Baluni Contracts: creating a npm library in a NX Monorepo
  • Baluni Core: creating a typescript library (baluni-core) in an nx monorepo that depends on other packages
  • Baluni CLI: creating a CLI application in an NX project
  • Baluni Backend: creating a NestJS backend in an NX monorepo
  • Baluni Web: creating a web3 NextJS application in an NX monorepo

You are very welcome to leave your comments, like the post and follow me if you liked this article and are interested in the following ones

. . . .
Terabox Video Player