Dependency updates in 2026: revisit Renovate, Dependabot and Updatecli before another library falls three majors behind
A dependency rarely breaks your system on the day it goes out of date. It breaks it eighteen months later, when a security fix lands only on a major version you skipped, and the upgrade that should have been a ten minute review becomes a two week project. Update bots exist to stop that drift. They also create a new problem: a flood of pull requests that nobody reads.
This post looks at three open-source tools that raise update pull requests for you: Renovate, Dependabot and Updatecli. The aim is not to crown a winner. The aim is to help you pick the one that fits your forge, your repositories and your team’s patience, and then configure it so that the pull requests get merged instead of ignored.
A scenario to keep us honest
Take an invented Nashik company that builds packhouse and export documentation software for grape and onion exporters in north Maharashtra. About 30 developers. Django for the back office, a Node.js and React frontend, a few Go services for weighbridge and cold room integrations, Dockerfiles for everything, and Helm values files for a small Kubernetes cluster. Most code sits on a self-managed GitLab CE server. Two open-source SDK repositories live on GitHub.
Before the grape season, an internal audit finds that Django is two releases behind, three base images are more than a year old, and one Go service still pins a library version that has a published advisory. Nobody was careless. Updates were simply nobody’s job.
Someone switches on Dependabot on the GitHub SDK repositories and gets eleven pull requests on the first morning. Someone else suggests “just do the same on GitLab” and finds that GitLab has no built-in Dependabot. That is the real question this post answers.
The short version
- Renovate is the most flexible of the three. It runs on GitHub, GitLab, Bitbucket, Azure DevOps, Gitea and Forgejo, and its documentation lists support for more than 90 package managers. It is AGPL-3.0, maintained by Mend, and you can use Mend’s free hosted app or run it yourself. The price of flexibility is a large configuration surface.
- Dependabot is the natural choice when your code is on GitHub. It is built in, needs one YAML file, and is now careful by default about brand new releases. Outside GitHub, the engine is open source but you have to build the wiring yourself or use a community project.
- Updatecli is a different kind of tool. It is not a package manager scanner first. It is a declarative update policy engine: you write a small YAML policy that says “read this value from here, check this, write it there”, and it opens a pull or merge request. It shines for Helm values, Dockerfiles, tool versions and platform files that the other two do not understand well.
For the Nashik team, a sensible answer is Renovate on GitLab for application dependencies, Dependabot on the two GitHub repositories, and Updatecli only for a few platform files where a precise policy helps. More on why below.
Where things stand on 26 October 2026
All versions below are from the projects’ own GitHub release pages, checked on 26 October 2026. Times are in IST.
- Renovate 44.181.6, released 25 October 2026 at about 9:25 PM. Renovate publishes releases very often; there were six releases between 24 and 25 October alone. Licence is AGPL-3.0. The repository was created in December 2016.
- Mend Renovate Community and Enterprise (the self-hosted server with a job scheduler and webhooks) 15.10.0, released 23 October 2026.
- Dependabot core v0.401.0, released 19 October 2026. Licence is MIT. Releases come roughly weekly. The Dependabot CLI is at v1.96.0, released 17 October 2026.
- Updatecli v0.123.0, released 22 October 2026. Licence is Apache 2.0. The project started in January 2020 and its most active contributor by commit count is its original author, Olivier Vernin.
None of these is abandoned. Release speed is not a problem here. If anything, Renovate’s pace means you should pin the Renovate version you run and update it on purpose, like any other dependency.
The first question: where does your code live
Before features, settle the forge.
- If everything is on GitHub.com, Dependabot costs you nothing to start and Renovate’s hosted app is also free. Either is reasonable.
- If you are on self-managed GitLab, Gitea, Forgejo or Bitbucket Data Center, Dependabot is not built in. Renovate supports these platforms directly. Updatecli also supports GitHub, GitLab, Gitea (and Forgejo through the Gitea API), Bitbucket Cloud, Bitbucket Server, Azure DevOps and plain Git.
- If you are mixed, as the Nashik team is, you can run more than one tool. That is fine as long as two tools never manage the same file. Two bots raising competing pull requests for the same
package.jsonis the fastest way to make people ignore both.
What each tool is
Renovate
Renovate scans a repository, finds dependency references in manifests, lock files, Dockerfiles, CI files and more, looks up newer versions from the registries, and raises pull requests. The first run opens an onboarding pull request with a renovate.json file. Once merged, Renovate starts raising updates.
The main ideas you need are these:
- Presets. Configuration usually starts with
extends.config:recommendedis the common base. The project’s own upgrade best practices page recommendsconfig:best-practices, which adds Docker digest pinning, GitHub Actions digest pinning, config migration pull requests, pinned dev dependencies, abandoned package detection, a three day minimum release age for npm, and weekly lock file maintenance. - Dependency Dashboard. An issue in the repository that lists every pending, open and closed update. It is on by default with
config:recommended. You can approve, retry or force an update from it. - Package rules. Almost everything can be matched by package name, update type, manager or file path, and then given its own schedule, grouping, labels or automerge setting.
Renovate is a Node.js program. You run it as a CLI, as a container image, as a GitHub Action, through the Renovate Runner project on GitLab CI, through Mend’s hosted app on GitHub.com and Bitbucket Cloud, or through the Mend Renovate Community self-hosted server.
Dependabot
Dependabot on GitHub has two parts that people often mix up.
- Security updates raise pull requests when GitHub has an advisory for a dependency in your dependency graph.
- Version updates are driven by
.github/dependabot.ymland keep dependencies current on a schedule.
The configuration is short: a list of updates, each with a package-ecosystem, a directory (or directories), and a required schedule. On top of that you have groups, ignore, allow, cooldown, open-pull-requests-limit, registries for private registries, and more recently multi-ecosystem-groups to combine, for example, Docker and Terraform updates into one pull request.
The engine underneath is dependabot-core, a set of Ruby gems. Its README says it can open pull requests against GitHub, GitHub Enterprise, Azure DevOps, GitLab, Bitbucket and AWS CodeCommit, but it is a library, so you need an entry point. GitHub’s recommended entry point is the Dependabot CLI, which GitHub says it uses in production. The CLI produces dependency diffs; it does not open pull requests, so you wire that part up yourself. For GitLab there is also a community project, dependabot-gitlab, which is separate from GitHub and had activity as recently as 26 October 2026.
Updatecli
Updatecli works from policies. Each policy is a YAML file (or a Go template) with three stages:
- Sources fetch a value, such as the latest tag of a container image, a Helm chart version or a GitHub release.
- Conditions check that prerequisites hold before any change is made.
- Targets write the value into a file and, if an SCM is configured, open a pull or merge request through an action.
Its plugin list in the repository includes resources for Docker images and digests, Dockerfiles, Helm, npm, PyPI, Maven, Cargo, Go, Terraform, YAML, JSON, TOML, XML, HCL, CSV, .tool-versions, Temurin JDK releases, Jenkins releases, AWS AMIs, shell commands and HTTP endpoints. It is a single Go binary and the README highlights --dry-run to preview changes.
The difference in mindset matters. Renovate and Dependabot ask “what dependencies does this repository have?” Updatecli asks “what exact change do you want, and under what conditions?”
Side by side, without a table
Licence and governance
- Renovate: AGPL-3.0, maintained by Mend with an open community. The AGPL matters if you modify Renovate and offer it to others as a network service; for running it internally against your own repositories, read the licence with your legal team rather than guessing.
- Dependabot core and CLI: MIT, maintained by GitHub. The hosted Dependabot service itself is part of GitHub, not something you run.
- Updatecli: Apache 2.0, a smaller independent community.
Forge support
- Renovate: GitHub, GitLab, Bitbucket, Azure DevOps, Gitea and Forgejo, with AWS CodeCommit, Gerrit and SCM-Manager listed as experimental.
- Dependabot: first class on GitHub only. Elsewhere through the CLI or community projects.
- Updatecli: GitHub, GitLab, Gitea, Forgejo through Gitea, Bitbucket Cloud and Server, Azure DevOps, and generic Git without pull requests.
What it understands
- Renovate: the widest package manager coverage of the three, plus custom regex managers for files it does not know.
- Dependabot: a solid list of mainstream ecosystems (npm, pip, uv, Bundler, Maven, Gradle, Go modules, Cargo, NuGet, Composer, Docker, Helm, Terraform, GitHub Actions and others), resolved through the real package managers so lock files stay consistent.
- Updatecli: whatever you describe in a policy. It does not discover every dependency unless you use its autodiscovery feature, and it is strongest for platform and configuration files.
Noise control
- Renovate: schedules (cron syntax),
prHourlyLimit,prConcurrentLimit(default 10 per repository),branchConcurrentLimit, groups, Dependency Dashboard approval, and per-package rules. Security pull requests are created even when the concurrent limit is reached. - Dependabot:
schedulewithdaily(which means Monday to Friday),weekly,monthly,cronand atimezone;open-pull-requests-limitdefaulting to five version update pull requests; a separate fixed limit of ten for security update pull requests; andgroups. - Updatecli: you decide when the pipeline runs. Noise is mostly a matter of how many policies you write.
Waiting before taking a new release
This is the area that changed most in the last two years, because of supply chain attacks through freshly published packages.
- Renovate’s
minimumReleaseAge(earlier calledstabilityDays) makes it wait a set time after each release before suggesting it. Its docs suggest 14 days before automerging third-party dependencies. It relies on the registry’s own release timestamp, not a timestamp the maintainer can set. - Dependabot’s
cooldowndelays version updates by a number of days, with separate values for major, minor and patch where the ecosystem supports semantic versioning. GitHub’s documentation now says that on GitHub.com Dependabot applies a default cooldown of three days to version updates even when you configure nothing. That default does not apply to security updates. - Updatecli has no single equivalent setting; you would express it as a condition in the policy.
Automerge
- Renovate can automerge pull requests or even branches, by update type, and by default uses the platform’s native automerge. Its docs warn that if you do not enforce required status checks on the platform, a pull request can be merged before tests finish.
- Dependabot does not automerge on its own. The usual pattern is a GitHub Actions workflow plus GitHub’s auto-merge on protected branches.
- Updatecli can be told to merge through its action settings, but most teams keep a human in the loop.
How these bots actually decide
It helps to know the mechanism, because most surprises come from it.
- Extraction. The bot parses files to find dependency names and current versions. Renovate and Dependabot know the file formats. Updatecli only reads what your policy points at.
- Lookup. It asks the registry for available versions, filters by your rules (ignore lists, allowed update types, release age), and picks a target.
- Update. For lock files, Renovate and Dependabot run the real package manager to regenerate them. This is why they need network access to registries and sometimes credentials for private ones.
- Branch and pull request. It pushes a branch, opens a pull request with release notes where it can find them, and keeps the branch rebased as the base branch moves.
- Waiting for you. CI runs. A human or an automerge rule decides.
Step 3 is also where the security risk lives. Some ecosystems run code during resolution; Dependabot’s README calls out setup.py and .gemspec as examples. GitHub’s hosted service wraps dependabot-core with a credential proxy so registry secrets are never handed to it. Renovate disables package manager scripts by default through ignoreScripts, and the free Mend-hosted app does not allow scripts at all. If you self-host either tool, you inherit that responsibility.
A worked plan for the Nashik team
Step 1: one owner and one rule
Name one person per repository group who owns update pull requests for the season. Write one rule: no repository is managed by two bots.
Step 2: Renovate on self-managed GitLab
Run Renovate as a scheduled GitLab CI pipeline from a small dedicated project, using a bot account with only Developer access to the repositories it should touch. Pin the Renovate image version. A starting renovate.json for the Django and Node repositories could look like this:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:best-practices"],
"timezone": "Asia/Kolkata",
"schedule": ["* 9-17 * * 1-5"],
"prHourlyLimit": 2,
"prConcurrentLimit": 5,
"minimumReleaseAge": "3 days",
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"matchDepTypes": ["devDependencies"],
"groupName": "frontend dev tooling",
"automerge": true,
"minimumReleaseAge": "14 days"
},
{
"matchPackageNames": ["django"],
"matchUpdateTypes": ["major"],
"dependencyDashboardApproval": true
}
]
}
What this says in plain words: work only during office hours on weekdays, never open more than two pull requests an hour or five at once, wait three days before suggesting any new release, group and automerge small dev tooling bumps only after two weeks, and never raise a Django major upgrade until someone ticks it on the dashboard. Before you enable automerge, make a successful pipeline a merge requirement in the GitLab project settings, or the automerge rule is only a hope.
Step 3: Dependabot on the two GitHub repositories
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "10:00"
timezone: "Asia/Kolkata"
open-pull-requests-limit: 5
cooldown:
default-days: 5
semver-major-days: 30
groups:
go-minor-and-patch:
update-types: ["minor", "patch"]
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
Grouping minor and patch bumps turns eleven pull requests into one or two. Security updates still arrive on their own, without the cooldown, which is what you want.
Step 4: Updatecli for the platform files
The Helm values for the cluster pin an ingress controller chart and an internal base image tag. Neither Renovate nor Dependabot knows the internal policy (“only take 1.x of this chart, and only if our staging values file already has it”). An Updatecli policy can say exactly that:
name: Bump web base image in production values
scms:
default:
kind: gitlab
spec:
url: "https://gitlab.example.internal"
owner: "platform"
repository: "cluster-values"
branch: "main"
token: '{{ requiredEnv "GITLAB_TOKEN" }}'
actions:
default:
kind: gitlab/mergerequest
scmid: default
sources:
baseImage:
kind: dockerimage
spec:
image: "registry.example.internal/base/python-web"
versionfilter:
kind: semver
pattern: "~3.2"
targets:
prodValues:
kind: yaml
scmid: default
sourceid: baseImage
spec:
file: "prod/web/values.yaml"
key: "$.image.tag"
Run it with --dry-run first. Keep these files out of Renovate’s scope with ignorePaths so only one tool owns them. Treat the hostnames above as placeholders, not real endpoints.
Step 5: what changes for the audit next season
The Django and base image findings now show up as small weekly pull requests and a dashboard item, not as a surprise in an audit. The Go advisory arrives as a security pull request within a day of GitHub publishing it. The team’s real work moves from “find out what is stale” to “read a short changelog and merge”.
Security and trust notes
- The bot is a privileged user. It can push branches to every repository it manages. Give it the least access that works, a separate account, and a token you can rotate. Our earlier post on secret scanning with Gitleaks, TruffleHog and detect-secrets covers what to do if that token ever leaks.
- Lock file regeneration runs package managers. Keep scripts disabled unless you truly need them, and on self-hosted Renovate review
allowedCommandsbefore usingpostUpgradeTasks. An emptyallowedCommandslist means no post-upgrade commands run. - Release age is a cheap defence. A three day wait would not stop every malicious package, but many malicious releases are found and pulled within days. Keep security updates outside the wait.
- Pin what runs your pipelines. Digest pinning for container images and commit SHA pinning for GitHub Actions, both part of Renovate’s
config:best-practices, stop a tag being moved under you. Pair it with image signature checks where you can. - An update bot is not a scanner. It tells you a newer version exists and, with advisory data, that a fix exists. It does not tell you what is exploitable in your running image. Keep a vulnerability scanner in CI as well.
Operational costs people forget
- CI minutes. Every update pull request runs your pipeline, and every rebase runs it again. Rate limits and grouping are as much about CI cost as about attention.
- Registry rate limits. Self-hosted Renovate talks to many registries. Fetching release notes from GitHub without a token can hit GitHub’s anonymous limits quickly, so Renovate’s running guide asks you to set
RENOVATE_GITHUB_COM_TOKENwith a read-only GitHub.com token whenever you run on any platform other than GitHub.com. - Private registries. Each tool needs credentials for internal npm, PyPI or container registries. Store them in the CI secret store, not in the config file.
- Upgrading the bot itself. Renovate ships almost daily. Pin it and let Renovate raise a pull request for its own image, reviewed like any other.
- People time. The honest cost is review. If nobody owns the queue, a perfect configuration still produces a pile of stale pull requests.
Decision guide
- Code only on GitHub, mainstream ecosystems, small team: start with Dependabot, add
groupsandcooldown, done. - Self-managed GitLab, Gitea, Forgejo or Bitbucket: Renovate, self-hosted through CI or the Mend Community server.
- Many repositories with shared rules: Renovate with a shared preset repository that every project extends.
- Platform repositories full of Helm values, Terraform variables and tool version files with house rules: Updatecli for those files, alongside one of the others.
- Strict “nothing changes without a human” culture: any of the three, with automerge off and Dependency Dashboard approval or manual Updatecli runs.
A short checklist
- One bot per file, written down.
- A schedule in your own time zone and office hours.
- Concurrent and hourly pull request limits set.
- Minor and patch updates grouped.
- A release age or cooldown for version updates, with security updates exempt.
- Required pipeline success before any automerge.
- A named owner for the update queue.
- The bot’s own version pinned and updated on purpose.
Common mistakes
- Turning it on everywhere on day one. Start with a few repositories and a low hourly limit, especially on the first run when the backlog is largest.
- Closing major update pull requests to make them go away. With Renovate, closing an update pull request tells it to skip that version, and it stays skipped until someone recreates it from the dashboard. Do this a few times and that is how a library falls three majors behind quietly.
- Automerge without required checks. Renovate’s own docs warn about this.
- Assuming “daily” means every day. For Dependabot it means Monday to Friday.
- Letting two tools fight over one file.
About a hands-on drill
No drill was run for this post. The configuration snippets above are written from each project’s documentation and are meant as starting points; try them on a test repository before rolling them out.
Unlearn, re-learn
Unlearn the idea that dependency updates are a quarterly clean-up job. That habit is exactly what makes them painful. Re-learn them as a small, steady flow: a few grouped pull requests a week, a short wait before trusting brand new releases, a quick read of the changelog, and a merge. The tool matters less than the habit. Pick the one that fits your forge, make it quiet enough that people actually read what it sends, and keep at it through the busy season too.
Sources
- Renovate README and configuration options
- Renovate minimum release age and upgrade best practices
- Renovate self-hosted configuration
- Renovate releases and Mend Renovate CE and EE releases
- Dependabot options reference
- dependabot-core README and releases
- Dependabot CLI
- dependabot-gitlab community project
- Updatecli README and releases
Releted Posts
Secret scanning in 2026: revisit Gitleaks, TruffleHog and detect-secrets before another API key lands in a commit
Picture a software company in Bhubaneswar that builds cold chain tracking and export paperwork software for seafood processors and exporters along the Odisha and north Andhra coast (an invented example, not a real client).
Read moreContainer image signing in 2026: revisit cosign, Notation and in-toto attestations before you trust another image tag
Picture a software company in Rajkot that builds production planning and job work software for foundries, forging units and engineering workshops across Saurashtra (an invented example, not a real client).
Read moreMesh VPNs in 2026: revisit Headscale, NetBird and plain WireGuard before you open another SSH port to the internet
Take a pump manufacturer in Coimbatore that makes agricultural and domestic pumps at two plants, one near the city and a smaller one at Kaniyur (an invented example, not a real client).
Read more