Pitfalls of a Monorepo

At Lightning AI, we made the decision to use a monorepo a while back. By and large, we’ve been really happy with it. It’s made supporting developers within a diverse and complex code ecosystem much simpler.

None of these are particularly surprising, nor are they necessarily fatal – but they are worth being aware of before you commit, particularly if you’re a smaller organization:

Many SaaS Analysis Tools Don’t Work

Many SaaS-based analysis tools make deep assumptions that repo == project. Some look for a lockfile in the root of the repo and just won’t proceed without it.

Some tools we found were just not gonna work with a monorepo:

Some tools that did pass this particular filter:

Some tools are just stuck in a middle ground of kinda-sorta working, but… maybe not perfectly – and maybe not once the needs if different sub-projects diverge. For example, CodeFactor forces you to choose a Python version repo-wide. We have some projects in Python 2.x, and some in 3.x. Not a perfect fit – but not necessarily fatal just yet. We’re hobbling along with the switch set to 3.x.

Code Coverage Reporting Can Be a Mess

Most coverage tracking plugins want to report paths relative to the project root, not the repo root. This can lead to intermingled results, and bad data. So far we’ve had to tweak the configuration of every coverage-reporting plugin to compensate for this.

For example, our setup for SimpleCov and CodeCov looks something like this:

require 'simplecov'
SimpleCov.start('rails') do
root File.expand_path('..', Dir.pwd) if ENV['CI']
# ...
if ENV['CI']
require 'codecov'
SimpleCov.formatter = SimpleCov::Formatter::Codecov

We’ve also had annoyances where having warnings about reductions in coverage bites us on PRs that affect projects where code coverage is not supported. Line counts increase, pushing the percentage code covered down. Our only solution to this so far has been to explicitly configure CodeCov to ignore every project directory where code coverage isn’t actually enabled.

Tools Get Slower

While a PR might only touch one project, all the analyses for all the projects will be executed. This can slow things down considerably as your codebase grows.

It’s Better If You Roll Your Own

All of these problems so far share one thing in common: If we were rolling our own, we could easily avoid them. Organizations with thousands of engineers often have both the time and the need to customize their tools (e.g. Facebook’s work on Mercurial) or to build new tools (e.g. Android team’s Repo tool) and thus may feel fewer of the pain-points that come from a monorepo versus what a smaller org might experience.

We’re a smaller team without the resources to set up a more custom CI / analysis flow just yet. In the meantime, we have a few tools set to not block builds – and other tools we’re just passing on, or running locally. Developers have been advised to be mindful of whether any particular results are relevant to their PRs, and ignore as necessary. Not a scalable solution, but perfectly reasonable for now.


If you’re accustomed to a model of merging into a development branch, and then periodically merging that into a master branch, you’re going to need to prepare for a much greater degree of coordination overhead around that. You’re probably way better off with a simpler flow model of merging feature branches directly to master and not having an intermediate staging area.


We love our monorepo, and we’re sticking with the technique. Setting up our own in-house tools for CI and analysis has had its time horizon moved forward because of it, which does add to the cost side of things but we feel like the reduced overhead is well worth it.

Monkey Bread

My familys recipe for monkey bread, which varies from the traditional by being a biscuit not a dessert.

Enterprise-Ready IPv4

This arose as a bit of a joke that bounced around among several friends and I. I thus present to you, IPv4, if it were Enterprise Ready.

An Unusual Case For Cucumber

Today I came across a case against Cucumber, and I have a couple bones to pick. More importantly, I want to elaborate a bit on the author’s comments about enjoying the Gherkin syntax, and expand on an idea there.

Fast GeoIP Queries in MySQL

Many moons ago, I tried to use the GeoIP database, via MySQL – and discovered that MySQL was doing the wrong thing with the queries. Naturally, I found some tricks to make it faster.

The AAIA ACES Datasets

Recently, I’ve been introduced to the AAIA’s ‘ACES’ datasets. These datasets aim to describe the make, model, and configuration of pretty much every vehicle in recent history.

Kill it With Fire Friday

I previously wrote about an idea I had for managing technical debt in the face of continuous and inevitable business pressures. I want to take a moment to follow up with some of the comments I’ve received on the technique, how it evolved, and where it proved strong/weak.

Know What You're Actually Testing

Getting At Awkward Code, For Great Testing

A couple days ago, I wound up helping out a colleague on a problem he was having coming up with an appropriate test case for a piece of code in a Rails app. It reminded me that I had wanted to talk about how structuring your code affects what you are actually testing, and how that related to what you want to test.

Shamir's Secret Sharing

Shamir’s Secret Sharing is a mechanism by which N people may each have a piece of of information, such that when any M people come together the pieces can be used to reproduce a secret – but if only M-1 pieces are brought together, you have zero bits of the secret.

Zero-Day Magento EE Cache Poisoning Attack


Magento Enterprise Edition is vulnerable to poisoning of its page cache under some configurations due to inappropriate trust of HTTP Host header values.

Prefab Overrides Considered Harmful

Punny title notwithstanding, I have decided that “prefab overrides” in Unity are more trouble than they are worth. The idea of course is to allow parametric variation of instances within a scene, but in practice I just seem to wind up with accidental breakage where overrides get lost because of a change to the prefab itself.

Unity's Reflective/Diffuse is Broken. Here's the Fix.

The Reflective/Diffuse shader shipping with Unity 2.6.0 (haven’t checked 2.6.1 just yet) does not work properly when the object is lit exclusively with vertex lighting. Here’s how you fix it – it’s just one line.

A Brief Treatise on Events and the Object Lifecycle in Unity

The Problem

Almost every headache I’ve had with Unity has ultimately come down to two simple but fairly amorphous problems. My goal is to make the nature and implications of those problems clear, and present a possible solution that Unity Technologies could implement to (hopefully) solve them.

Pathfinding in Unity

When it comes to pathfinding in Unity, you can roll your own, or use one of two publicly available resources. The most drool-worthy is AngryAnt’s Path. Having gotten way too familiar with the problem of pathfinding myself, and wanting a better workflow and richer capabilities than my home-grown solution affords me, I decided to poke around with AngryAnt’s code last night.

License of UnityUnit

I was asked today about what license UnityUnit is released under. Since I didn’t explicitly state the rights and terms one can’t reasonably assume that it is safe to use it! So, I am officially noting that all versions of UnityUnit to date are released under the BSD license. Enjoy!

Unit Testing in Unity

Until now, there has been no good solution for building unit tests for games built using Unity. As of today, there is. Get the package (version: 20090704) here.

Ruby on Rails and Performance. An Interesting Experience.

I was out sick yesterday, but I managed to spend a little time working on “SB”. I’ve been playing with Ruby on Rails for a couple months, but today I really began to grok where the limits are with respect to Ruby, Rails, and performance.

Copyright © 2018 - Jon Frisby - Powered by Octopress