· Dependency Management · 5 min read
Renovate Custom Managers: The Dependency Update Tool Dependabot Can't Match
Dependabot handles the easy cases. Renovate custom managers handle everything else — Terraform modules, Helm chart versions buried in YAML, Docker image tags in shell scripts, and anything else your team has invented.

Keeping dependencies up to date is one of those platform engineering problems that sounds boring until you’re the one explaining to leadership why a six-month-old Log4j version is still in production. Automated dependency updates are non-negotiable. The question is which tool you reach for — and whether it can actually handle your real-world setup.
Most teams start with Dependabot because it’s built into GitHub and requires zero configuration for common cases. That’s genuinely valuable. But the moment your stack steps outside npm, pip, and Go modules — the moment you have Helm chart versions pinned in a values.yaml, or a Terraform module version hardcoded in a README, or a base image tag sitting inside a shell script — Dependabot taps out. Renovate doesn’t.
What Makes Renovate Different
Renovate is a dependency update bot built around the idea that dependency versions can appear anywhere, not just in files it already knows about. It ships with over 100 built-in managers covering everything from package.json to Cargo.toml to GitHub Actions. But its real power is the custom managers feature: a way to teach Renovate about version strings it has never seen before using regular expressions.
Custom Managers in Practice
A custom manager tells Renovate three things:
- Which files to scan (
fileMatch) - How to find version strings in those files (
matchStrings) - Where to look up new versions (
datasourceTemplate,depNameTemplate,versioningTemplate)
Here’s a concrete example. Say your team pins Helm chart versions in a config/versions.yaml file that looks like this:
charts:
cert-manager: 1.14.2
ingress-nginx: 4.9.1
external-secrets: 0.9.13Dependabot won’t touch this. Renovate can:
{
"customManagers": [
{
"customType": "regex",
"fileMatch": ["config/versions\\.yaml"],
"matchStrings": ["(?<depName>[a-z-]+): (?<currentValue>[\\d\\.]+)"],
"datasourceTemplate": "helm",
"registryUrlTemplate": "https://charts.jetstack.io"
}
]
}Renovate will now open PRs against those chart versions as new releases land — with changelogs attached, grouped if you want, and subject to whatever merge policies you’ve configured.
Terraform Module Versions in Arbitrary Files
Another common case: internal Terraform modules pinned in documentation or wrapper scripts.
# versions.tf (not a standard lockfile)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.5.1"
}Renovate’s built-in Terraform manager handles .tf files natively. But if your team has module versions scattered across custom config files:
{
"customManagers": [
{
"customType": "regex",
"fileMatch": ["\\.yaml$", "\\.json$"],
"matchStrings": ["terraform_module_version:\\s*\"?(?<currentValue>[\\d\\.]+)\"?"],
"depNameTemplate": "terraform-aws-modules/vpc/aws",
"datasourceTemplate": "terraform-module"
}
]
}Docker Image Tags in Shell Scripts
Build scripts often hardcode image tags:
docker run --rm \
-v $(pwd):/workspace \
hashicorp/terraform:1.7.4 \
init{
"customManagers": [
{
"customType": "regex",
"fileMatch": ["\\.sh$", "Makefile"],
"matchStrings": ["hashicorp/terraform:(?<currentValue>[\\d\\.]+)"],
"depNameTemplate": "hashicorp/terraform",
"datasourceTemplate": "docker"
}
]
}Renovate will now track Docker Hub for new Terraform releases and open a PR updating your script. The same pattern works for any image in any file format.
Renovate vs Dependabot: A Direct Comparison
| Feature | Renovate | Dependabot |
|---|---|---|
| Setup | renovate.json in repo or central config | .github/dependabot.yml |
| Hosting | Self-hosted or Mend.io cloud | GitHub-hosted only |
| Custom managers | Yes — regex against any file | No |
| Custom datasources | Yes | No |
| Grouped PRs | Yes, fully configurable | Limited (by ecosystem) |
| Automerge | Yes, with fine-grained rules | Yes, with branch protection |
| Scheduling | Cron-based, per package | Weekly/daily per ecosystem |
| PR rate limiting | Configurable | Configurable |
| Changelogs | Inline in PR body | Inline in PR body |
| Monorepo support | Excellent | Basic |
| Private registries | Yes | Yes |
| Regex versioning | Yes | No |
| Terraform | Native + custom | Native (lockfiles only) |
| Helm | Native + custom | No |
| GitHub Actions | Native | Native |
| Docker | Native + custom | Native |
When Dependabot Is Enough
Dependabot wins on zero-friction setup. If your stack is npm, pip, bundler, Go modules, GitHub Actions, and Docker — all managed through their standard manifest files — Dependabot is already configured the moment you enable it. No JSON to write, no self-hosting to think about, no learning curve.
For teams running a straightforward microservice stack where the only dependencies that matter are npm packages and container base images in Dockerfiles, Dependabot does the job and costs nothing in configuration overhead.
When You Need Renovate
Reach for Renovate when:
- You have non-standard version files — anything Dependabot’s fixed list of managers doesn’t cover
- You need grouped PRs — one PR for all patch updates across all packages, rather than 47 individual PRs on Monday morning
- You have a monorepo — Renovate understands workspace dependencies and can batch updates intelligently
- You want automerge with confidence — Renovate’s automerge rules are granular enough to automerge patch updates for low-risk packages while requiring review for major bumps
- You run Helm — Dependabot has no Helm support; Renovate ships a native Helm manager
- You want centralised config — Renovate supports a
renovate-configrepo that all your repos inherit from, so you manage update policy in one place
Setting Up Renovate
The fastest path is the Renovate GitHub App. Install it on your org, add a renovate.json to a repo, and it starts opening PRs within minutes.
A minimal starting config:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"schedule": ["before 6am on Monday"],
"automerge": false,
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"matchPackagePatterns": ["*"],
"automerge": true
}
]
}This runs updates once a week, automerges patch versions, and requires review for minor and major bumps — a sane default for most teams.
For centralised control across many repos, create a renovate-config repository and have each repo extend it:
{
"extends": ["github>your-org/renovate-config"]
}One place to update policy. Every repo picks it up.
The Bottom Line
Dependabot is the right starting point for simple stacks on GitHub. Renovate is the right tool for everything else — and in practice, almost every real platform engineering environment eventually has something that falls outside Dependabot’s coverage.
Custom managers are what push Renovate from “better Dependabot” to “the only tool that can actually keep our entire platform up to date”. If you’ve ever manually updated a version string somewhere because no bot knew to look there, that’s the gap custom managers close.