diff --git a/services/depfu/depfu.service.js b/services/depfu/depfu.service.js
index b35daf9f904f31a78ddf2243f3933457dd80e450..fd26a9e4297db719cb4e122ffb087d70a6342970 100644
--- a/services/depfu/depfu.service.js
+++ b/services/depfu/depfu.service.js
@@ -1,18 +1,22 @@
 import Joi from 'joi'
-import { BaseJsonService } from '../index.js'
+import { BaseJsonService, InvalidParameter, redirector } from '../index.js'
 
 const depfuSchema = Joi.object({
   text: Joi.string().required(),
   colorscheme: Joi.string().required(),
 }).required()
 
-export default class Depfu extends BaseJsonService {
+class Depfu extends BaseJsonService {
   static category = 'dependencies'
-  static route = { base: 'depfu', pattern: ':user/:repo' }
+  static route = {
+    base: 'depfu/dependencies',
+    pattern: ':vcsType(github|gitlab)/:project+',
+  }
+
   static examples = [
     {
       title: 'Depfu',
-      namedParams: { user: 'depfu', repo: 'example-ruby' },
+      namedParams: { vcsType: 'github', project: 'depfu/example-ruby' },
       staticPreview: this.render({
         text: 'recent',
         colorscheme: 'brightgreen',
@@ -29,13 +33,31 @@ export default class Depfu extends BaseJsonService {
     }
   }
 
-  async fetch({ user, repo }) {
-    const url = `https://depfu.com/github/shields/${user}/${repo}`
+  async fetch({ vcsType, project }) {
+    const separatorPosition = project.lastIndexOf('/')
+    if (separatorPosition < 0) {
+      throw new InvalidParameter()
+    }
+    const user = encodeURIComponent(project.substr(0, separatorPosition))
+    const repo = project.substr(separatorPosition)
+    const url = `https://depfu.com/${vcsType}/shields/${user}/${repo}`
     return this._requestJson({ url, schema: depfuSchema })
   }
 
-  async handle({ user, repo }) {
-    const { text, colorscheme } = await this.fetch({ user, repo })
+  async handle({ vcsType, project }) {
+    const { text, colorscheme } = await this.fetch({ vcsType, project })
     return this.constructor.render({ text, colorscheme })
   }
 }
+
+const legacyRoutes = [
+  redirector({
+    category: 'dependencies',
+    route: { base: 'depfu', pattern: ':user/:repo' },
+    transformPath: ({ user, repo }) =>
+      `/depfu/dependencies/github/${user}/${repo}`,
+    dateAdded: new Date('2022-01-11'),
+  }),
+]
+
+export default { ...legacyRoutes, Depfu }
diff --git a/services/depfu/depfu.tester.js b/services/depfu/depfu.tester.js
index 04aeaf2b02cf952cc59caa83264481d38acdcb5b..36b8b2375728e3c452bd8d038aa3f95893db9478 100644
--- a/services/depfu/depfu.tester.js
+++ b/services/depfu/depfu.tester.js
@@ -10,13 +10,51 @@ const isDependencyStatus = Joi.string().valid(
 
 export const t = new ServiceTester({ id: 'depfu', title: 'Depfu' })
 
-t.create('depfu dependencies (valid)')
-  .get('/depfu/example-ruby.json')
+t.create('depfu Github dependencies (valid)')
+  .get('/dependencies/github/depfu/example-ruby.json')
   .expectBadge({
     label: 'dependencies',
     message: isDependencyStatus,
   })
 
-t.create('depfu dependencies (repo not found)')
-  .get('/pyvesb/emptyrepo.json')
+t.create('depfu Github dependencies (repo not found)')
+  .get('/dependencies/github/pyvesb/emptyrepo.json')
   .expectBadge({ label: 'dependencies', message: 'not found' })
+
+t.create('depfu Gitlab dependencies (valid)')
+  .get('/dependencies/gitlab/depfu/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: isDependencyStatus,
+  })
+
+t.create('depfu Github dependencies (no separator)')
+  .get('/dependencies/github/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: 'invalid parameter',
+  })
+
+t.create('depfu Gitlab dependencies (valid with subgroup)')
+  .get(
+    '/dependencies/gitlab/shields-example-group/subgroup/example-nodejs.json'
+  )
+  .expectBadge({
+    label: 'dependencies',
+    message: isDependencyStatus,
+  })
+
+t.create('depfu Gitlab dependencies (repo not found)')
+  .get('/dependencies/gitlab/fdroid/nonexistant.json')
+  .expectBadge({ label: 'dependencies', message: 'not found' })
+
+t.create('depfu Gitlab dependencies (no separator)')
+  .get('/dependencies/gitlab/example-ruby.json')
+  .expectBadge({
+    label: 'dependencies',
+    message: 'invalid parameter',
+  })
+
+t.create('legacy route (assume "github" as a default VCS)')
+  .get('/depfu/example-ruby.svg')
+  .expectRedirect('/depfu/dependencies/github/depfu/example-ruby.svg')