Automating Dependency Updates with Renovate
Permalink to "Automating Dependency Updates with Renovate"Part of Continuous Dependency Monitoring, this page gives a production renovate.json and its Dependabot equivalent for turning dependency drift and security advisories into reviewable pull requests automatically.
Quick Reference
Permalink to "Quick Reference"| Property | Value |
|---|---|
| Config file location | renovate.json (repo root) — also .github/renovate.json, .renovaterc.json, or renovate key in package.json |
| Schema | https://docs.renovatebot.com/renovate-schema.json |
| Base preset | extends: ["config:recommended"] |
| Routine schedule | schedule: ["before 6am on monday"] |
| Security fix schedule | vulnerabilityAlerts.schedule: ["at any time"] |
| Version strategy | rangeStrategy: "pin" (applications) |
| Lockfile refresh | lockFileMaintenance: { enabled: true } |
| Patch automerge | packageRules[].automerge: true on matchUpdateTypes: ["patch"] |
| Status surface | Dependency Dashboard issue + per-PR checks |
Keep one configuration file per repository. Renovate reads it on every run and reconciles open pull requests against it, so the file is the single source of truth for update behaviour.
How Renovate Automates the Update Feed
Permalink to "How Renovate Automates the Update Feed"Renovate runs as a hosted GitHub App (or a self-hosted job), scans your manifests and lockfile against the registry, and opens a pull request for every dependency that has a newer version — with the lockfile already regenerated and a changelog in the description. It runs in two modes from one config: a slow, batched cadence governed by schedule for routine upkeep, and an immediate, out-of-band pull request driven by vulnerabilityAlerts when an update closes a known advisory. This is the remediation half of a monitoring loop — the detection half (advisory feeds and CI audit gates) and the triage flow that decides what to do with each finding are covered in the parent workflow.
Canonical Implementation
Permalink to "Canonical Implementation"The following renovate.json is a complete, production-ready configuration for a deployed application. Commit it to the repository root.
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard",
":semanticCommits"
],
"timezone": "UTC",
"schedule": ["before 6am on monday"],
"prConcurrentLimit": 5,
"prHourlyLimit": 2,
"rangeStrategy": "pin",
"rebaseWhen": "conflicted",
"labels": ["dependencies"],
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 6am on monday"]
},
"vulnerabilityAlerts": {
"labels": ["security", "dependencies"],
"schedule": ["at any time"],
"prPriority": 10
},
"packageRules": [
{
"description": "Automerge patch updates once CI is green",
"matchUpdateTypes": ["patch", "pin", "digest"],
"automerge": true,
"automergeType": "pr",
"platformAutomerge": true
},
{
"description": "Group all non-major dev tooling into one PR",
"matchDepTypes": ["devDependencies"],
"matchUpdateTypes": ["minor", "patch"],
"groupName": "dev dependencies"
},
{
"description": "Require manual review for major bumps",
"matchUpdateTypes": ["major"],
"automerge": false,
"addLabels": ["breaking"]
}
]
}
The vulnerabilityAlerts.schedule of "at any time" is what makes security fixes bypass the Monday window; prPriority: 10 floats them above routine pull requests when the concurrency limit is reached. rangeStrategy: "pin" rewrites "^5.4.0" to an exact "5.4.10" so every install is reproducible. Renovate regenerates the lockfile with whichever package manager it detects in the repository, so Enforcing Package Manager Versions with Corepack is what keeps the bot’s lockfile output byte-identical to what a developer would produce locally.
Pinning changes what the manifest means. A caret range is a standing instruction to the installer — “take any 5.x release you find” — which is resolved at install time and can differ between machines and dates. After pinning, the manifest names one build, and the only way the version moves is a pull request you can read, test and revert:
Variant Examples
Permalink to "Variant Examples"Dependabot equivalent (dependabot.yml)
Permalink to "Dependabot equivalent (dependabot.yml)" If you prefer GitHub’s native bot, the closest equivalent lives at .github/dependabot.yml. Dependabot has no direct analogue to rangeStrategy: pin (it respects your manifest ranges) or lockFileMaintenance, but it covers scheduling and grouping:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "06:00"
timezone: "UTC"
open-pull-requests-limit: 5
labels: ["dependencies"]
groups:
dev-dependencies:
dependency-type: "development"
update-types: ["minor", "patch"]
Security fixes are handled separately by Dependabot’s own security-updates feature, which is enabled at the repository level rather than in this file and always runs immediately. The two bots overlap on scheduling, grouping and security urgency, and diverge on how much control they give you over the resolved version:
Grouping monorepo packages
Permalink to "Grouping monorepo packages"In a monorepo, collapse related ecosystem updates into a single pull request so reviewers see one coherent change instead of a dozen:
{
"packageRules": [
{
"description": "One PR for the whole ESLint toolchain",
"matchPackageNames": ["eslint"],
"matchPackagePrefixes": ["@typescript-eslint/", "eslint-config-", "eslint-plugin-"],
"groupName": "eslint"
}
]
}
Automerge only patch, hold minor and major
Permalink to "Automerge only patch, hold minor and major"To automerge patch updates while still requiring review for anything that could change behaviour, scope automerge narrowly and disable it explicitly for the wider types:
{
"packageRules": [
{ "matchUpdateTypes": ["patch"], "automerge": true },
{ "matchUpdateTypes": ["minor", "major"], "automerge": false, "dependencyDashboardApproval": true }
]
}
dependencyDashboardApproval: true holds minor and major updates in the Dependency Dashboard until you tick a checkbox, so they never open unsolicited.
Gotchas and Edge Cases
Permalink to "Gotchas and Edge Cases"-
Automerge is only as safe as your test suite.
platformAutomergewill merge a green pull request with no human in the loop. If CI does not exercise the updated code path, a broken — or maliciously republished — patch reaches the default branch unreviewed. Restrict automerge topatch/pin/digest, keep a required status check, and never automergeminorormajor. The blast radius shrinks further if the update cannot run arbitrary code during install at all, which is the case made in Disabling npm Install Scripts — apostinstallhook in an automerged patch executes on your CI runner with whatever credentials that job holds. -
rangeStrategy: pinchanges the meaning of your manifest. Pinning rewrites caret and tilde ranges to exact versions, so yourpackage.jsonbecomes a list of frozen versions and Renovate itself becomes the only path to an upgrade. That is the intent for a deployed application, but it is the wrong default for a published library, where consumers need range flexibility — usebumporwidenthere instead. -
lockFileMaintenanceis noisy if left on a tight schedule. It refreshes the entire lockfile — every transitive pin — on its cadence, which can produce a large, hard-to-review diff. Keep it on the same weekly window as routine updates, not"at any time", or it will open a sprawling pull request whenever any transitive dependency ships a release. A bot-authored lockfile diff still deserves the review discipline described in Detecting Lockfile Tampering in Pull Requests: check that changedresolvedURLs still point at your registry and that everyintegrityfield moved together with its version, because a large machine-generated diff is exactly where a hand-edited line hides best. -
Security fixes silently wait if
vulnerabilityAlertsis unset. Without an explicitvulnerabilityAlertsblock, advisory fixes are subject to your routinescheduleand can sit unopened until the next window — up to a week of avoidable exposure. Always give it"schedule": ["at any time"]. The block also requires that Dependabot alerts are enabled on the repository, since Renovate reads that feed to know a package is vulnerable. -
Concurrency limits can starve the security queue. With
prConcurrentLimitreached by routine bumps, a new security pull request may not open until a slot frees. SettingprPriorityhigh onvulnerabilityAlerts(as in the canonical config) ensures the security fix jumps ahead rather than queueing behind cosmetic updates.
Verification Steps
Permalink to "Verification Steps"1. Dry-run the configuration locally
Permalink to "1. Dry-run the configuration locally"Before relying on the hosted app, run Renovate in dry-run mode to see exactly which pull requests it would open without creating any:
LOG_LEVEL=debug npx renovate --dry-run=full --platform=github \
--token="$RENOVATE_TOKEN" OWNER/REPO
Expected output — the log lists each detected update and the branch it would create, and confirms no writes occurred:
INFO: Dependency extraction complete {"deps": 42}
INFO: DRY-RUN: Would create PR: Update dependency vite to v5.4.10
INFO: DRY-RUN: Would automerge PR after checks
INFO: Renovate is exiting with a success code
2. Validate the config file schema
Permalink to "2. Validate the config file schema"Catch a malformed renovate.json before it reaches a run:
npx --package renovate -c renovate-config-validator
Expected output on a valid file:
INFO: Validating renovate.json
INFO: Config validated successfully
3. Confirm behaviour on the Dependency Dashboard
Permalink to "3. Confirm behaviour on the Dependency Dashboard"After the first real run, open the Dependency Dashboard issue Renovate creates. It lists open pull requests, pending scheduled updates, and any awaiting-approval items. A security fix should appear under Open immediately with the security label, while routine bumps sit under Pending with their next scheduled time. If a security fix is stuck under Pending, the vulnerabilityAlerts block is missing or Dependabot alerts are not enabled on the repository.
Frequently Asked Questions
Permalink to "Frequently Asked Questions"Where does the renovate.json file go?
In the repository root by default. Renovate also accepts .github/renovate.json, .renovaterc.json, or a renovate key in package.json. Only one of them is read per repository and the first match in that search order wins, so a leftover file under .github can silently override the root config you are editing. Keep exactly one and delete the rest.
Should Renovate pin or widen version ranges?
For applications, use rangeStrategy pin so the manifest records an exact version and every install is reproducible. For published libraries, prefer bump or widen so consumers are not forced onto a single version and cannot end up carrying duplicated copies of the same dependency. Pinning is the safer default for anything you deploy rather than publish.
Is it safe to automerge dependency updates?
Automerge is safe only for update types your test suite fully covers, which in practice means patch-level updates behind a required, green CI check. Automerging minor or major updates without human review risks shipping a breaking change, or a maliciously republished version, straight to the default branch. Keep platformAutomerge scoped to patch, pin and digest updates.
Why is Renovate not opening any pull requests?
Check three things in order. The Dependency Dashboard issue lists every update Renovate knows about and the reason each one is held. The schedule comes next, since a weekly window means nothing opens between runs. Then prConcurrentLimit and prHourlyLimit, which stop new pull requests once the cap is reached. dependencyDashboardApproval also holds updates until you tick their checkbox.
Related
Permalink to "Related"- Continuous Dependency Monitoring — the full loop this automated update feed plugs into: advisory scanning, CI audit gates, triage, and the alert-to-remediation SLA.
- Dependency Pinning Best Practices — why
rangeStrategy: pinand a committed lockfile make every automated update reproducible. - Vulnerability Tracking & Triage — what to do with the security pull requests Renovate raises before you merge them.
- Registry & Package Manager Hardening — the install-side controls that make an automerged update safe: registry proxying, install-script lockdown, and a pinned package manager.