Monorepos
A monorepo houses multiple applications, services, or packages in a single version-controlled repository. While this model simplifies dependency management and cross-team collaboration, it introduces unique challenges for automated static analysis and code coverage:
- Slow static analysis: Monorepos can be large, leading to longer analysis times.
- Developer tool conflicts: Different components may use different tools or versions, causing conflicts.
- Diverse quality preferences: Teams may have varying preferences for tools and configurations, complicating standardization.
- Separate test suites: Each component may have its own test suite, making it difficult to aggregate results.
Qlty was built with monorepos in mind, helping you to improve code quality and coverage even in large projects.
Code analysis
For code quality analysis, Qlty offers the following features to help you manage monorepos.
Sandboxed tool installations
In a monorepo, different components may use different tools, languages, or versions. Getting all of these installed and running consistently across platforms can be a challenge. Sometimes, as tools versions change, they may not be compatible with each other within the same repository.
Qlty provides a unified interface to install and upgrade these tools making it easier to run them in a consistent manner on every developer machine. Each linter and its dependencies are installed into a separate sandbox, so they will never conflict. This is especially useful in monorepos where different components may require different versions of the same tool.
Note: The Qlty CLI is compatible with MacOS, Linux, and Windows.
Prefixes and package files
Many static analysis tools tie their configuration to the root of the repository. This can make it difficult (“config hell”) or impossible to tailor the analysis to the needs of each component in a monorepo.
Qlty makes it easy to enable plugins with independent configurations using the prefix
option. This can be combined with the package_file
option to easily use different versions of the same tool in different components, or even different tools altogether.
Accelerated analysis
Static analysis can be slow, especially in monorepos with many components. Qlty provides several features to speed up static analysis like concurrency and caching. With these features, we are often able to run linters faster through Qlty than running them directly.
Also, Qlty is designed to perform differential analysis, meaning that it only analyzes the files that have changed in a given pull request. This approach makes it possible to get results quickly without interrupting developer flow.
Triage rules
Code quality is never one-size-fits-all, especially in a monorepo. Qlty offers an advanced triage and reporting system that can be tailored for monorepos.
This allows maintainers within the monorepos to independently control their static analysis results without impacting other sub-projects. Here are some examples:
Ignore issues based on directory patterns
Override the level of certain issues in a directory
Adjust the issue mode for a directory
Directory-level visualization
The Qlty Cloud web application provides clear, directory-level reporting for monorepos. This allows you to see the code quality of each component in your monorepo at a glance, making it easy to identify areas that need attention.
Code coverage
Diff coverage
When working with monorepos, traditional coverage metrics like total coverage can be misleading. A large monorepo might have high overall test coverage, but the new code in a pull request could still be completely untested.
Diff coverage (sometimes called patch coverage) solves this problem by focusing only on the code that has changed in a pull request. Qlty can report Diff Coverage as a commit status and through code review comments.
Coverage tags
Monorepos often employ selective testing strategies where only the tests relevant to changed components run on each commit. This approach significantly improves CI performance but creates challenges for coverage reporting.
Qlty addresses this with Coverage Tags, which allow you to upload separate groupings of code coverage data. For example, you can use a unique tag for each service in the monorepo. This enables clear, independent reporting of coverage.
Also, Qlty can “carry forward” coverage data from previous runs to infer the total coverage of the HEAD, allowing you to maintain a complete picture.
Coverage merging
Monorepos with multiple languages, frameworks, or parallelized test suites often generate multiple coverage reports that need to be combined. Qlty supports two powerful merging approaches: client-side merging and server-side merging.
Client-side merging:
- Multiple coverage reports are combined locally before uploading to Qlty
- Ideal when all tests run on a single machine or shared filesystem
- Example:
qlty coverage publish reports/*.lcov
Server-side merging:
- Individual coverage reports are uploaded separately and combined by Qlty
- Perfect for distributed CI systems where tests run across multiple machines
- Uses a parts count to track when all reports have been received
- Example:
qlty coverage publish --total-parts-count=3 report.lcov
These approaches can be combined together or with coverage tags for maximum flexibility. For instance, you might have three parts for “unit” coverage and two parts for “integration” coverage, all of which Qlty can merge appropriately.
This flexibility makes Qlty ideal for complex monorepo setups where coverage data comes from multiple sources and needs to be aggregated intelligently.
Related links
- Ignoring Issues - Learn how to ignore issues in your monorepo
- Project Configuration - Detailed reference for
qlty.toml
configuration options - Analysis Configuration - Configure how Qlty analyzes your code
- Coverage Merging - Detailed guide on merging coverage reports
- Code Coverage Setup - How to set up code coverage for your project