Dependabot vs Renovate: dependabot.yml vs renovate.json Compared

Last updated:

Dependabot and Renovate both do one thing: open pull requests when your dependencies fall behind. Dependabot is GitHub-native, configured via .github/dependabot.yml, built into every GitHub repo, and zero-setup for public projects. Renovate is open-source (maintained by Mend), configured via renovate.json (or .github/renovate.json), and covers a much wider package-manager ecosystem with deeper configuration knobs for grouping, scheduling, and monorepo paths. Choose Dependabotwhen you want "good enough, zero config"; choose Renovate when you want grouped updates, schedule control, and ecosystem-specific rules.

Editing renovate.json by hand? Paste it into Jsonic's JSON Validator first — a single misplaced comma will silently disable Renovate on your repo.

Validate renovate.json

Setup: dependabot.yml location vs renovate.json/.renovaterc

Both tools are configured by a single file in your repo. The file path, format, and default behavior when the file is missing differ.

AspectDependabotRenovate
Config file path.github/dependabot.yml (only valid location)renovate.json, .github/renovate.json, renovate.json5, .renovaterc, or package.json > renovate
FormatYAMLJSON, JSON5, or YAML (preview)
Comments?Yes (#)Only in .json5 variant
If file missingDisabled (no PRs)Onboarding PR auto-created with default config
Enable required?Yes — file presence enables itYes — install Mend Renovate App (or self-host)

Dependabot needs nothing beyond the YAML file. Renovate needs both the app installation AND a config (or it'll create one for you via an onboarding PR). For self-hosted Renovate, you also run the Renovate Bot binary on a schedule (CLI, GitHub Action, or container).

Configuration syntax side-by-side

Here's the same intent — "update npm dependencies weekly, group all@types/*packages, ignore major bumps for React" — expressed in both formats.

Dependabot (.github/dependabot.yml):

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Etc/UTC"
    groups:
      types-packages:
        patterns:
          - "@types/*"
    ignore:
      - dependency-name: "react"
        update-types: ["version-update:semver-major"]
      - dependency-name: "react-dom"
        update-types: ["version-update:semver-major"]
    open-pull-requests-limit: 10

Renovate (renovate.json):

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "schedule": ["before 5am on Monday"],
  "timezone": "Etc/UTC",
  "packageRules": [
    {
      "description": "Group all @types/* packages",
      "matchPackagePatterns": ["^@types/"],
      "groupName": "types packages"
    },
    {
      "description": "Block major bumps for React",
      "matchPackageNames": ["react", "react-dom"],
      "matchUpdateTypes": ["major"],
      "enabled": false
    }
  ],
  "prConcurrentLimit": 10
}

The Renovate config is shorter because it inherits from config:recommended, a shareable preset that sets sensible defaults (rangeStrategy, lockfileMaintenance, etc.). Dependabot has no preset/extends mechanism — every repo's YAML stands alone.

Comparison table: 12 dimensions

The headline differences, scored honestly. Neither tool is universally better; they optimize for different priorities.

DimensionDependabotRenovate
SchedulingInterval keywords (daily/weekly/monthly) + day + timeFull DSL: cron-like, "every weekday before 5am", timezones, automergeSchedule
GroupingPer-ecosystem groups (added 2023); patterns onlyNative cross-ecosystem grouping; packageRules with regex, paths, update-types
Package managers~30 (npm, pip, maven, gomod, bundler, cargo, docker, gh-actions, etc.)90+ (adds Bazel, Helm, Terraform, Pre-commit, Pipenv, Poetry, asdf, mise, Nix, etc.)
LanguagesStrong on JS/Python/Ruby/Java/Go; weaker on niche stacksBroad and deep across all major + niche languages
Monorepo supportMulti-directory via directories array (2024); no workspace awarenessWorkspace-aware (npm/pnpm/yarn); matchFileNames for path scoping
Auto-mergeNone native — wire via GitHub Actions + fetch-metadataBuilt-in automerge: true; supports branch automerge + schedule
Vulnerability alertsBuilt-in "Dependabot Security Updates" from GitHub AdvisoriesvulnerabilityAlerts reads GH Advisories + OSV; configurable
Lockfile maintenanceUpdates lockfile alongside package.json; no separate "refresh-only" modelockFileMaintenance opens lockfile-only PRs on a schedule
Custom rulesLimited to ignore, allow, groupspackageRules match by name/pattern/path/updateType/manager; chainable
Ecosystem / presetsNo shareable config; one-repo-one-fileShareable presets (config:recommended, community presets, org-wide configs)
CostFree everywhere on GitHub.comFree on public repos and most private (Mend Cloud); paid only for Mend SCA add-ons
Ownership / hostingGitHub (Microsoft) — closed-source serviceMend (formerly WhiteSource) — open-source AGPL-3.0; self-hostable

Schedule and timing: cron-like syntax vs interval keywords

Scheduling is one of the most common tuning knobs — "don't open PRs during business hours," "only on weekends," "monthly cadence for non-critical deps." The two tools take very different approaches.

Dependabot scheduling uses three keys: interval(daily, weekly, monthly), an optional day (monday–sunday), and an optional time (HH:MM) with timezone.

schedule:
  interval: "weekly"
  day: "saturday"
  time: "06:00"
  timezone: "America/New_York"

That's the full vocabulary. You cannot say "every weekday before 5am" or "the first Monday of each month" in Dependabot.

Renovate scheduling uses a natural-language DSL via the later parser. Strings like before 5am, after 10pm every weekday,every weekend, and on the first day of the month all work:

{
  "schedule": ["before 5am every weekday", "every weekend"],
  "timezone": "America/New_York",
  "automergeSchedule": ["after 10pm and before 5am every weekday"]
}

Renovate also separates "when to open PRs" (schedule) from "when to automerge" (automergeSchedule), letting you queue PRs during work hours but merge overnight when CI finishes.

Grouping: Renovate's killer feature

Without grouping, 30 packages going up in a week = 30 PRs. Both tools now support grouping, but the depth differs significantly.

Renovate grouping sits inside packageRules and composes freely. Match by name, pattern, depType, fileName, manager, update-type, or any combination, then assign a groupName:

{
  "packageRules": [
    {
      "description": "Group all React-related deps",
      "matchPackagePatterns": ["^react", "^@types/react"],
      "groupName": "react ecosystem"
    },
    {
      "description": "Group all dev dependencies into one PR per week",
      "matchDepTypes": ["devDependencies"],
      "matchUpdateTypes": ["minor", "patch"],
      "groupName": "dev dependencies (non-major)",
      "schedule": ["before 5am on Monday"]
    },
    {
      "description": "Group all GitHub Actions",
      "matchManagers": ["github-actions"],
      "groupName": "github actions"
    },
    {
      "description": "Group all Docker base image updates",
      "matchManagers": ["dockerfile", "docker-compose"],
      "groupName": "docker images"
    }
  ]
}

Dependabot grouping (introduced 2023, stabilized 2024) is a per-ecosystemgroups map with patterns, exclude-patterns,dependency-type (production/development), and update-types:

updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      react-ecosystem:
        patterns:
          - "react*"
          - "@types/react*"
      dev-deps:
        dependency-type: "development"
        update-types:
          - "minor"
          - "patch"

Dependabot grouping covers ~80% of real-world needs. Where Renovate pulls ahead: cross-ecosystem groups (npm + docker in one PR), groups with their own schedule, groups with their own automerge rule, and groups defined via shareable presets. If you find yourself wishing Dependabot grouping had "just one more knob," that's usually the signal to evaluate Renovate.

Security alerts: Dependabot Security Updates vs Renovate vulnerabilityAlerts

Both tools can open PRs in response to known vulnerabilities, sourced primarily from the GitHub Security Advisories database.

Dependabot Security Updates is a separate product from the version-update PRs configured in dependabot.yml. You enable it in GitHub repository settings (or org-wide). When GitHub Security Advisories publishes a CVE that affects one of your dependencies, Dependabot opens a PR bumping just the vulnerable package to the patched version, regardless of your dependabot.yml schedule. These PRs ignore the open-pull-requests-limitand ignore lists by default. You can't easily configure them per-ecosystem; the toggle is repo-wide.

Renovate vulnerabilityAlertsreads the same GitHub Advisories plus the OSV database. It's enabled by default and configurable like any other rule. You can adjust labels, assignees, schedule (e.g., bypass normal schedule for security PRs), and even prefix:

{
  "vulnerabilityAlerts": {
    "enabled": true,
    "labels": ["security", "priority/high"],
    "schedule": ["at any time"],
    "automerge": false,
    "commitMessagePrefix": "[SECURITY]"
  }
}

In practice, Dependabot Security Updates is the de-facto baseline for GitHub repos because it's already wired up. Many teams use Dependabot for security alerts while letting Renovate handle routine updates — but as noted in the FAQ below, running both for security can create duplicate PRs unless you turn one side off.

Migration: from Dependabot to Renovate (or vice versa)

Migrating between the two is mostly a config translation exercise. Both tools read the same lockfiles and package manifests; nothing changes about your code.

Dependabot → Renovate (most common direction):

  1. Install the Mend Renovate App on GitHub Marketplace (free for public repos and most private).
  2. Wait for the onboarding PR; merge it to accept the default config or edit first.
  3. Translate your dependabot.yml into renovate.json. Use Renovate's configuration options reference; most fields map directly: ignorepackageRules with enabled: false, groupspackageRules with groupName, schedule.intervalschedule string.
  4. Validate the JSON with Jsonic's JSON Validator or use npx --package renovate -- renovate-config-validator locally.
  5. Delete .github/dependabot.yml. (Leaving it = duplicate PRs.)
  6. Optionally disable Dependabot version updates in repo settings.

Renovate → Dependabot:

  1. Translate renovate.json to .github/dependabot.yml. Accept that some features won't map: shareable presets, automergeSchedule, cross-ecosystem groups, scheduled lockfileMaintenance, packageRules with complex matchers.
  2. For each ecosystem you use (npm, pip, etc.), add a updates: entry with package-ecosystem, directory, and schedule.
  3. Translate Renovate packageRules into Dependabot groups, ignore, and allow sections.
  4. Uninstall the Mend Renovate App (or set {"enabled": false} in renovate.json) and delete renovate.json.
  5. Enable Dependabot Security Updates in repo settings if you want vulnerability PRs.

Both translations take 15–60 minutes for a typical repo, longer for monorepos with custom rules. Do it on a feature branch and watch the first round of PRs before merging the config to main.

Key terms

Dependabot
GitHub's built-in dependency-update bot. Opens PRs to bump out-of-date dependencies and patch known vulnerabilities. Configured via .github/dependabot.yml. Acquired by GitHub from the original team in 2019 and rebuilt as a native GitHub feature.
Renovate
Open-source dependency-update tool maintained by Mend (formerly WhiteSource). Supports 90+ package managers, runs as a hosted GitHub App or self-hosted bot, and is configured via renovate.json / renovate.json5. Licensed under AGPL-3.0.
Lockfile maintenance
A separate PR type that refreshes transitive dependency versions in the lockfile (package-lock.json, pnpm-lock.yaml, etc.) without touching the manifest. Renovate exposes this as lockFileMaintenance; Dependabot does not have a direct equivalent.
Grouped updates
Combining multiple package bumps into a single PR. Reduces PR noise and CI cost. Renovate groups via packageRules with groupName; Dependabot groups via the groups key under each updates: entry.
Automerge
Automatically merging a dependency-update PR after CI passes, without human review. Renovate ships native automerge with automerge: true. Dependabot delegates to GitHub Actions — you write a workflow that calls gh pr merge --auto after using the dependabot/fetch-metadata action.
Scheduling DSL
A small domain-specific language for expressing when bot actions run. Renovate uses the later parser, accepting strings like before 5am every weekday or on the first day of the month. Dependabot uses a fixed set of interval keywords plus a single day/time.

Frequently asked questions

Should I use Dependabot or Renovate?

It depends on what you want from dependency automation. Use Dependabot if you are on GitHub, want zero setup, and are happy with one PR per package update. It is built into GitHub, free for every repository (public and private), and the default vulnerability scanner powering GitHub Security Alerts. Use Renovate if you want grouped updates (e.g., all @types/* in one PR), fine-grained scheduling (weekends only, off-hours, monthly cadence), monorepo-aware filtering by path, lockfile-only refresh, or coverage of less common package managers like Bazel, Helm, Terraform, or Pre-commit. Renovate is also free on public repos and most private repos via Mend Cloud, and it can self-host. Many shops start with Dependabot, hit its grouping or scheduling limits, then migrate to Renovate. There is no wrong choice — both reduce the manual work of staying current.

Is Renovate free?

Yes for nearly all common cases. Renovate the tool is open-source under the AGPL-3.0 license, free to self-host on any infrastructure. The hosted Mend Renovate App on GitHub Marketplace is free for public repositories and free for private repositories on the Open Source tier. Mend Cloud (the commercial hosted offering) charges only for the optional Mend SCA security platform and enterprise SSO/audit features — basic dependency-update PRs remain free. You can verify pricing at mend.io/renovate. By contrast, Dependabot is also fully free on GitHub.com, including private repos, since GitHub bundled it into the platform after the 2019 acquisition. So neither tool charges for the core update-PR workflow on standard GitHub usage.

Can I use Dependabot and Renovate together?

Technically yes but it is rarely a good idea. Running both means duplicate PRs for every update, doubled CI cost, and merge conflicts when one updates the lockfile while the other has an open PR. The one supported pattern is letting Dependabot handle Security Updates (the automatic PRs created from GitHub Security Advisories) while Renovate handles all routine version updates. Disable Renovate vulnerability handling with "vulnerabilityAlerts": {"enabled": false} and tell Dependabot to only open PRs for security: in dependabot.yml, set the "open-pull-requests-limit" to 0 for non-security ecosystems. The cleaner approach for most teams is to pick one tool and disable the other entirely. If you migrate to Renovate, remove .github/dependabot.yml; if you stay on Dependabot, remove renovate.json.

How do I group all React-related updates into one PR?

Renovate makes this trivial with packageRules and matchPackagePatterns. Add to renovate.json: {"packageRules": [{"matchPackagePatterns": ["^react", "^@types/react"], "groupName": "react ecosystem"}]}. All packages matching the pattern open one combined PR with a unified version bump. You can layer more rules — group major bumps separately from minors/patches, or pin certain packages while grouping others. Dependabot added a "groups" feature in mid-2023 that handles this for the same ecosystem (npm): in dependabot.yml under updates, set groups: react-ecosystem: patterns: ["react*", "@types/react*"]. Dependabot grouping is per-ecosystem and less expressive than Renovate (no cross-ecosystem groups, no automerge-by-group rules until recently) but covers the common case. Both reduce PR noise dramatically.

Does Dependabot support monorepos?

Yes, but with caveats. Dependabot scans by ecosystem and directory pair — in dependabot.yml you list every package-ecosystem (npm, pip, etc.) plus its "directory" path. For a monorepo with 20 npm workspaces you either declare 20 entries (one per package) or use the "directories" array (plural, added in 2024) to point one ecosystem block at multiple paths with shared config. Dependabot does NOT understand workspace protocol links — it bumps each workspace independently. Renovate has first-class monorepo support: it detects workspaces in npm/pnpm/yarn, hoists the version bump to the right place, and you can use "matchFileNames" to scope rules to specific paths. For monorepos with cross-package dependencies and complex grouping needs, Renovate is the smoother experience.

Can renovate.json have comments?

No — renovate.json is strict JSON (RFC 8259) and rejects // or /* */ comments. If you try to add comments, Renovate will throw a config parse error and skip the repo. Two workarounds: (1) Use renovate.json5 instead. Renovate accepts JSON5 (a superset of JSON that allows comments, trailing commas, unquoted keys, single quotes) when the filename ends in .json5. Rename your config and you get full commentability. (2) Use a "description" field on every rule. packageRules accepts "description" as a top-level key on each rule object — Renovate ignores it functionally but it shows up in dashboards and PR bodies, making it both a comment and self-documentation. dependabot.yml is YAML which natively supports # comments, so this concern only applies to the Renovate side.

What is the difference between automerge in Dependabot and Renovate?

Both tools can automerge PRs that pass CI, but the mechanism differs. Dependabot has no native automerge — you wire it via GitHub Actions: add the "dependabot/fetch-metadata" action and call gh pr merge --auto on PRs that match a filter (e.g., update-type is version-update:semver-patch). The logic lives in your workflow file. Renovate has automerge built in. Set "automerge": true at the top level of renovate.json (automerges everything that passes CI) or scope it per packageRule: {"matchUpdateTypes": ["patch", "minor"], "automerge": true}. Renovate also supports "automergeType": "branch" (no PR at all — pushes directly to the default branch) and "automergeSchedule" to limit merges to safe hours. Renovate is more configurable; Dependabot is more explicit but forces you to write workflow YAML.

How do I lock major version updates?

Both tools can ignore or defer major updates, with different syntax. Dependabot: in dependabot.yml, add ignore entries under each update block. ignore: - dependency-name: "react" update-types: ["version-update:semver-major"]. That blocks major bumps for React only; other packages still get majors. Renovate: use packageRules with matchUpdateTypes. {"packageRules": [{"matchUpdateTypes": ["major"], "enabled": false}]} disables every major bump globally. To scope to specific packages: {"matchPackageNames": ["react"], "matchUpdateTypes": ["major"], "enabled": false}. Renovate also has "rangeStrategy": "bump" vs "replace" to control whether package.json ranges widen on minor updates, which Dependabot does not expose. For framework-pinned projects (Next.js, Vue, Angular), locking majors is the most common config tweak users make.

Further reading and primary sources