This blog is a work in progress.

writing.

Structure your application with a monorepo

Cover Image for Structure your application with a monorepo
Anthony Manikhouth
Anthony Manikhouth

Imagine a company that need to build a landing page, a marketplace, a dashboard and a blog. All should carry the same brand identity, and share some common components. They would gain from dividing their codebase into multiple projects, thus creating multiple packages that can be reused between them, a package handling the UI, another one handling the API, another one handling the authentication, etc.

But this comes with a cost. Each project would need to be deployed separately, and each project would need to be maintained separately. A simple commit or code review would require to go through multiple repositories to make sure everything is set up correctly.

The monorepo solution

A monorepo is a single code repository that contains multiple projects, packages, programming languages, etc. It also allows you to have a single CI/CD pipeline, and to deploy/release all your projects at once.

With fractif, our Ethereum-based luxury assets PoC marketplace, we decided to use a monorepo. We have a single repository that contains all our projects, smart contracts, frontend, backend, etc.

The decision was motivated by a few factors:

  • Smart Contracts are written in Solidity but Hardhat can also be used to compile and generate TypeScript types for them. This means that we can use the types generated by Typechain (integrated in Hardhat) in our frontend and backend projects written in TS. Thus, changes to the smart contracts can be reflected in the frontend and backend projects without having to manually update the types.
  • We wanted to have a single CI/CD pipeline, and to deploy all our projects at once based on the changes made to a given package/project. This is possible with Github Actions.
  • Having a landing page, a marketplace, a dashboard and a blog, all sharing the same brand identity, we wanted to have a single repository for all our projects, and to share the UI components between them. We could've done it with a single UI package that we could add as an npm dependency on each project. But by having this package in the same repository as the projects, we can make changes to the UI package and see the changes reflected in the projects without having to publish the package to npm and update the version in each project.
  • Being able to share tsconfig.json, eslint, prettier, tests config, ci/cd config, etc. between projects.
  • And many more.

Monorepo applied to Fractif, our Ethereum-based luxury assets PoC marketplace

Our monorepo is structured as follows:

  • packages contains all our packages that can be shareable between the projects:
    • ui contains all the UI components that are shared between the projects
    • api contains the API client that is shared between the projects
    • contracts contains the smart contracts
  • apps contains all our projects:
    • landing contains the landing page
    • marketplace contains the marketplace
    • dashboard contains the dashboard
    • blog contains the blog
    • cli contains the CLI
    • desktop contains the desktop app
    • docs contains the documentation
    • mobile contains the mobile app
  • root contains the root config files, like tsconfig.json, eslint, prettier, etc. theses files are shared between all the projects.
  • .github contains the Github Actions config files.
  • And you can imagine other folders like scripts that can be shared between projects.

The drawbacks

But it also comes with some drawbacks.

Hard to maintain

I love planning my projects and keep track of what I'm doing through GitHub Issues and Projects. But with a monorepo, it's hard to keep track of what's going on in each project. It can get messy really fast, especially on large open source projects (try having a look at Solana monorepo). In this case, labels can be used to filter the issues and projects can be used to group them.

Hard to scale

Monorepos are great for small projects, but they can get messy really fast on large projects. Need to modify a package that is used by multiple projects? Good luck. You'll have to make sure that the changes you make don't break the other projects. New to the project? Sad. You'll have to go through all the projects to understand how they work.

Conclusion

Monorepos come with its pros and cons, and while it has proven itself production-ready for us and for many other companies over the years, it's not a silver bullet. It's a great way to structure your application, but it also comes with some drawbacks. Based on your spesific needs, you might want to use a monorepo or not.

More reading