Table of contents
Renovating with Renovate
Renovate was originally created to scratch an internal itch, so weβve been both enjoying its capabilities and testing them from day one. When people get started or get comfortable with using Renovate, itβs pretty understandable that they might look at the Renovate project itself as a reference user. Weβve put together this post to share how we as βpower usersβ use Renovate in our day-to-day activity, as a little inspiration.
Installation and enablement
We host the Renovate source code on github.com, and so use the Mend Renovate hosted app for maximum convenience.

We use a renovate.json config file in the root so itβs easy for everyone to spot, and it extends our default organization preset in github>renovatebot/.github. Weβll describe how our organization preset works later.
Now that the repository is installed via the app, and onboarded via a config file, it means the hosted app will usually run:
- On schedule, usually every 1-2 hours
- On-demand, if anyone ticks an embedded checkbox in any Renovate Issue or PR
- As-needed if webhook activity indicates that a Renovate PR has been merged, Renovateβs config has been updated, or a notable package file has been edited any other way
Dependency update automation
Automating dependency updates is the main reason people use Renovate, and we aim to keep the project as up-to-date as possible. After all, a professional painter shouldnβt live in a house that needs a new coat, should they?
The key points about how we use Renovate to update dependencies are:
- We extend the config:base preset that all new accounts are recommended. Importantly this means that the most common βmonoreposβ already come pre-grouped without us needing to configure those.
- We set stabilityDays to 3, meaning that we donβt want any PRs created automatically for new releases which are less than 3 days old. There arenβt many circumstances where any project needs a release that soon, unless itβs an internal release or something youβre specifically waiting for.
- We donβt raise major updates by default. Instead, they are buffered for approval in the βDependency Dashboardβ, which is like a mini dashboard in the repository. This lets us raise them on-demand when we are ready for them.
- We defer updating Microsoftβs dev container for VS Code to once per month. It usually updates more often than that, but we donβt have any urgent need for updates and prefer to keep noise down.
- We donβt custom group package updates — unless they are from known monorepos which must be updated in lockstep. This way one bad update to a dependency doesnβt block all the other updates if they all combined into a single PR.
- We keep the default config:base settings of maximum 2 PRs created per hour or 20 concurrently, but we usually donβt get close to that at all, and try to merge PRs right away once they reach stability and pass our tests.
Organization default preset
The renovatebot organization on GitHub has a .github repository used to share common files, including Renovate configuration files. There are two files which are relevant:
- A renovate-config.json file which is used by Renovate to determine the default onboarding config whenever we add a new repository. By having this repository file in place, it means the hosted app proposes our custom config instead of the default, meaning one less step for us to perform every time a new repository is onboarded.
- A default.json file which is the orgβs default preset
Renovateβs org preset also contains some pretty clever βregex managerβ rules which we use to apply custom dependency updates to our Dockerfiles and documentation. Both of these are worthy of their own post!
Repository assimilation
Weβre a believer that great tools should fit into a developerβs workflows, rather than request developers adjust to a toolβs workflows. For Renovate, this means adapting to a projectβs conventions for branch naming, commit syntax, labeling, etc.
In Renovateβs case:
- We use semantic commits, defaulting to βchoreβ but using βbuildβ for non-dev dependencies so that each update triggers our semantic-release config.
- Speaking of semantic-release, we use βbuildβ semantic commit type — even though itβs a dev dependency, because we always want to test that any new update works and releases.
- We donβt have a need for labels, and donβt apply them. Renovate doesnβt pollute projectβs labels by default.
- Renovate automatically assigns two of the project maintainers to each PR.
Merge Confidence
A great new feature introduced by Mend last year is Merge Confidence, and we rely on it heavily.
We built Merge Confidence on the premise that:
- There is always the potential that new releases contain an unintentionally breaking change or bug.
- Relying on your own tests alone is rarely enough to be certain.
- By aggregating test results and version adoption amongst Renovateβs user base, we can determine with a high degree of accuracy whether a new release is safe or not.
In practice, that means Pull Requests for new versions look like this:

Based on the above, itβs clear why the Confidence is βHighβ and I have no problem merging it, especially as it passed my tests too.
Downstream automation
Another aspect of how we use Renovate to build Renovate is downstream automation. It was mentioned earlier that in most cases you donβt need new releases immediately after theyβre released, but internal packages are an exception that an increasing number of Renovate users utilize to improve productivity between projects and teams.
Similar to how many projects are built, Renovate is developed and published across multiple repositories. Once a new release of Renovate is made, we have repositories which build and publish a Docker Image as well as a GitHub Action. App users are often eager to try out new Renovate features right away, so we make sure there is no stability days restriction on our own packages and that PRs are created right away.
Further, there is no need for us to review or approve our own packages in this case, so we also enable branch automerge. What this means is that usually within about an hour of releasing Renovate, the downstream Docker and GitHub Action repositories have already received an automated upgrade of Renovate and are on their way to finishing the process. Because we release up to dozens of times per release, this is not something that can be handled manually.
Additionally, the Mend Renovate App also needs updating, and a similar process applies. In this case although we create the PR immediately, we do require a manual approval/merge before updating the hosted app, because sometimes there are new features which should ideally be observed post-upgrade just to make sure all goes smoothly. We wouldnβt want an accidental bug taking down the app βautomaticallyβ during an hour when nobodyβs watching closely, so we use a manual approval step for upgrading Renovate in the app. This is again not something which would scale well with manual dependency updates and commits.
Wrapping up
We hope sharing our experience with Renovate helps you find ways to tweak Renovate to your needs, including custom package updates, scheduling, stability, and workflow features. If you have any questions, always feel free to post to Renovateβs Discussion Forum.