diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index e3bc625bc0f5..71bf9ca99bbd 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -99,7 +99,8 @@ (define-module (gnu packages gnuzilla)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages sqlite)
   #:autoload (json parser) (json->scm)
-  #:export (all-mozilla-locales))
+  #:export (all-mozilla-locales
+            make-icecat-minimal))
 
 (define-public mozjs
   (package
@@ -720,7 +721,9 @@ (define icecat-source
                         "--sort=name"
                         icecat-dir)))))))))
 
-(define-public icecat-minimal
+(define* (make-icecat-minimal #:key
+                              moz-app-name
+                              branding-directory)
   (package
     (name "icecat-minimal")
     (version %icecat-version)
@@ -1013,16 +1016,11 @@ (define-public icecat-minimal
               (substitute* "build/RunCbindgen.py"
                 (("\"--frozen\",") ""))))
           (delete 'bootstrap)
-          (replace 'configure
+          (add-before 'configure 'setenv
             ;; configure does not work followed by both "SHELL=..." and
             ;; "CONFIG_SHELL=..."; set environment variables instead
-            (lambda* (#:key outputs configure-flags #:allow-other-keys)
-              (let* ((bash (which "bash"))
-                     (abs-srcdir (getcwd))
-                     (flags `(,(string-append "--prefix=" #$output)
-                              ,(string-append "--with-l10n-base="
-                                              abs-srcdir "/l10n")
-                              ,@configure-flags)))
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let ((bash (which "bash")))
                 (setenv "SHELL" bash)
                 (setenv "CONFIG_SHELL" bash)
 
@@ -1048,16 +1046,23 @@ (define-public icecat-minimal
                 (setenv "MOZBUILD_STATE_PATH"
                         (string-append (getcwd) "/.mozbuild"))
 
-                (format #t "build directory: ~s~%" (getcwd))
+                (format #t "build directory: ~s~%" (getcwd)))))
+          (add-before 'configure 'mozconfig
+            (lambda* (#:key configure-flags #:allow-other-keys)
+              (let ((flags `(,(string-append "--prefix=" #$output)
+                             ,(string-append "--with-l10n-base="
+                                             (getcwd) "/l10n")
+                             ,@configure-flags)))
                 (format #t "configure flags: ~s~%" flags)
 
                 (call-with-output-file "mozconfig"
                   (lambda (port)
                     (for-each (lambda (flag)
                                 (format port "ac_add_options ~a\n" flag))
-                              flags)))
-
-                (invoke "./mach" "configure"))))
+                              flags))))))
+          (replace 'configure
+            (lambda _
+              (invoke "./mach" "configure")))
           (replace 'build
             (lambda* (#:key (make-flags '()) (parallel-build? #t)
                       #:allow-other-keys)
@@ -1093,8 +1098,7 @@ (define-public icecat-minimal
                             (string-append #$output "/bin"))))
           (add-after 'install 'wrap-program
             (lambda* (#:key inputs #:allow-other-keys)
-              (let* ((lib (string-append #$output "/lib"))
-                     (gtk #$(this-package-input "gtk+"))
+              (let* ((gtk #$(this-package-input "gtk+"))
                      (gtk-share (string-append gtk "/share"))
                      (ld-libs '#$(cons
                                   (file-append
@@ -1112,7 +1116,8 @@ (define-public icecat-minimal
                                          ;; For the integration of native notifications
                                          ;; (same reason as icedove)
                                          "libnotify")))))
-                (wrap-program (car (find-files lib "^icecat$"))
+                (wrap-program (format #f "~a/lib/~a/~a"
+                                      #$output #$moz-app-name #$moz-app-name)
                   `("XDG_DATA_DIRS" prefix (,gtk-share))
                   ;; The following line is commented out because the icecat
                   ;; package on guix has been observed to be unstable when
@@ -1134,18 +1139,17 @@ (define-public icecat-minimal
                    "StartupNotify=true\nStartupWMClass=Icecat"))
                 (install-file desktop-file applications))))
           (add-after 'install-desktop-entry 'install-icons
-            (lambda _
-              (with-directory-excursion "browser/branding/official"
-                (for-each
-                 (lambda (file)
-                   (let* ((size (string-filter char-numeric? file))
-                          (icons (string-append #$output "/share/icons/hicolor/"
-                                                size "x" size "/apps")))
-                     (mkdir-p icons)
-                     (copy-file file (string-append icons "/icecat.png"))))
-                 '("default16.png" "default22.png" "default24.png"
-                   "default32.png" "default48.png" "content/icon64.png"
-                   "mozicon128.png" "default256.png"))))))))
+            (lambda* (#:key inputs #:allow-other-keys)
+              (for-each
+               (lambda (size)
+                 (let ((oldpath (string-append
+                                 #$branding-directory "/default" size ".png"))
+                       (newpath (string-append
+                                 #$output "/share/icons/hicolor/" size "x"
+                                 size "/apps/" #$moz-app-name ".png")))
+                   (mkdir-p (dirname newpath))
+                   (copy-file oldpath newpath)))
+               '("16" "22" "24" "32" "48" "64" "128" "256")))))))
     (native-search-paths
      (list (search-path-specification
             (variable "ICECAT_SYSTEM_DIR")
@@ -1169,6 +1173,10 @@ (define-public icecat-minimal
        (cpe-name . "firefox_esr")
        (cpe-version . ,(first (string-split version #\-)))))))
 
+(define-public icecat-minimal
+  (make-icecat-minimal #:moz-app-name "icecat"
+                       #:branding-directory "browser/branding/official"))
+
 (define %icecat-locales
   '("ach" "af" "an" "ar" "ast" "az" "be" "bg" "bn" "br" "bs" "ca" "cak"
     "ca-valencia" "cs" "cy" "da" "de" "dsb" "el" "en-CA" "en-GB" "eo" "es-AR"
diff --git a/gnu/packages/tor.scm b/gnu/packages/tor.scm
index 604be621157c..6eb0c7609f0b 100644
--- a/gnu/packages/tor.scm
+++ b/gnu/packages/tor.scm
@@ -562,9 +562,18 @@ (define torbrowser-assets
 Browser.")
     (license license:silofl1.1)))
 
-(define-public torbrowser
+(define* (make-torbrowser #:key
+                          moz-app-name
+                          moz-app-remotingname
+                          branding-directory
+                          assets
+                          locales
+                          base-browser-version)
+  (define base (make-icecat-minimal
+                #:moz-app-name moz-app-name
+                #:branding-directory branding-directory))
   (package
-    (inherit icecat-minimal)
+    (inherit base)
     (name "torbrowser")
     (version %torbrowser-version)
     (source
@@ -580,42 +589,45 @@ (define-public torbrowser
          "1c0p8aya7sh7nmawngkyzx2r02mvl9nd53hx2bl0jwvsj1vxxhca"))))
     (build-system mozilla-build-system)
     (arguments
-     (substitute-keyword-arguments (package-arguments icecat-minimal)
+     (substitute-keyword-arguments (package-arguments base)
        ((#:configure-flags flags '())
         #~(cons*
            "--without-relative-data-dir" ;store is read-only
            "--disable-base-browser-update"
            ;; Default is "default", which is the same as "nightly".
            "--enable-update-channel=release"
-           "--with-user-appdir=.torbrowser"
-           "--with-branding=browser/branding/tb-release"
+           ;; This is useless right now but it might be used in the future.
+           ;; (See nsAppFileLocationProvider.cpp.)
+           (string-append "--with-user-appdir=." #$moz-app-name)
+           (string-append "--with-branding=" #$branding-directory)
            (string-append "--prefix=" #$output)
-           (string-append "--with-base-browser-version=" #$version)
+           (string-append "--with-base-browser-version="
+                          #$base-browser-version)
            #$flags))
        ((#:phases phases)
         #~(modify-phases #$phases
-            (add-before 'configure 'setenv
+            (replace 'setenv
               (lambda _
                 (setenv "CONFIG_SHELL" (which "bash"))
                 ;; Install location is prefix/lib/$MOZ_APP_NAME.  Also
                 ;; $MOZ_APP_NAME is the executable name.  Default is
                 ;; "firefox".
-                (setenv "MOZ_APP_NAME" "torbrowser")
+                (setenv "MOZ_APP_NAME" #$moz-app-name)
                 ;; Profile location (relative to "~/.").  Default is
                 ;; lower($MOZ_APP_VENDOR/$MOZ_APP_BASENAME), which is:
                 ;; ~/.tor project/firefox.
-                (setenv "MOZ_APP_PROFILE" "torbrowser/browser")
+                (setenv "MOZ_APP_PROFILE" #$(in-vicinity
+                                             moz-app-name "browser"))
                 ;; WM_CLASS (default is "$MOZ_APP_NAME-$MOZ_UPDATE_CHANNEL").
-                (setenv "MOZ_APP_REMOTINGNAME" "Tor Browser")
+                (setenv "MOZ_APP_REMOTINGNAME" #$moz-app-remotingname)
                 ;; Persistent state directory for the build system (default is
                 ;; $HOME/.mozbuild).
                 (setenv "MOZBUILD_STATE_PATH"
                         (in-vicinity (getcwd) ".mozbuild"))
-                (setenv "MOZ_CHROME_MULTILOCALE"
-                        (string-join '#$%torbrowser-locales))
+                (setenv "MOZ_CHROME_MULTILOCALE" (string-join '#$locales))
                 ;; Make build reproducible.
                 (setenv "MOZ_BUILD_DATE" #$%moz-build-date)))
-            (add-before 'configure 'mozconfig
+            (replace 'mozconfig
               (lambda* (#:key configure-flags #:allow-other-keys)
                 (with-output-to-file "mozconfig"
                   (lambda ()
@@ -623,9 +635,6 @@ (define-public torbrowser
                     (for-each (lambda (flag)
                                 (format #t "ac_add_options ~a~%" flag))
                               configure-flags)))))
-            (replace 'configure
-              (lambda _
-                (invoke "./mach" "configure")))
             ;; See tor-browser-build/projects/firefox/build.
             (add-before 'configure 'copy-firefox-locales
               (lambda _
@@ -637,7 +646,7 @@ (define-public torbrowser
                                                (string-suffix? lang path))
                                              '#$all-mozilla-locales)
                                        (in-vicinity l10ncentral lang)))
-                   '#$%torbrowser-locales))))
+                   '#$locales))))
             (add-after 'copy-firefox-locales 'copy-basebrowser-locales
               (lambda _
                 (let ((l10ncentral ".mozbuild/l10n-central"))
@@ -661,7 +670,7 @@ (define-public torbrowser
                              "translation-base-browser/~a/*"
                              "~a/~a/browser/chrome/browser/"))
                        lang l10ncentral lang)))
-                   '#$%torbrowser-locales))))
+                   '#$locales))))
             (add-after 'copy-basebrowser-locales 'copy-torbrowser-locales
               (lambda _
                 (let ((l10ncentral ".mozbuild/l10n-central"))
@@ -698,7 +707,7 @@ (define-public torbrowser
                        (format port "  locale/~a/ (chrome/locale/~a/*)~%"
                                lang lang)
                        (close port)))
-                   '#$%torbrowser-locales))))
+                   '#$locales))))
             (add-before 'build 'fix-addons-placeholder
               (lambda _
                 (substitute*
@@ -717,13 +726,24 @@ (define-public torbrowser
               (lambda _
                 (system (string-join '("./mach package-multi-locale --locales"
                                        "en-US $MOZ_CHROME_MULTILOCALE")))))
-            (add-after 'install 'deploy-assets
+            (add-after 'install 'deploy-fonts
+              (lambda* (#:key inputs #:allow-other-keys)
+                (let ((lib (string-append #$output "/lib/" #$moz-app-name)))
+                  ;; Fonts
+                  (copy-recursively (in-vicinity #$assets "fontconfig")
+                                    (in-vicinity lib "fontconfig"))
+                  (substitute* (in-vicinity lib "fontconfig/fonts.conf")
+                    (("<dir>fonts</dir>")
+                     (format #f "<dir>~a</dir>" (in-vicinity lib "fonts"))))
+                  (delete-file-recursively (in-vicinity lib "fonts"))
+                  (copy-recursively (in-vicinity #$assets "fonts")
+                                    (in-vicinity lib "fonts")))))
+            (add-after 'deploy-fonts 'deploy-tor-assets
               (lambda* (#:key inputs #:allow-other-keys)
                 (let ((lib (in-vicinity #$output "lib/torbrowser"))
                       (tor #$(this-package-input "tor-client")))
                   ;; TorBrowser/Data/Tor/torrc-defaults
-                  (copy-recursively (in-vicinity
-                                     #$torbrowser-assets "TorBrowser")
+                  (copy-recursively (in-vicinity #$assets "TorBrowser")
                                     (in-vicinity lib "TorBrowser"))
                   (substitute*
                       (in-vicinity lib "TorBrowser/Data/Tor/torrc-defaults")
@@ -733,20 +753,10 @@ (define-public torbrowser
                   ;; The geoip and geoip6 files are in the same directory as
                   ;; torrc-defaults.  (See TorProcess.sys.mjs.)
                   (mkdir-p (in-vicinity lib "TorBrowser/Data/Tor"))
-                  (copy-file (in-vicinity tor "share/tor/geoip")
-                             (in-vicinity lib "TorBrowser/Data/Tor/geoip"))
                   (copy-file (in-vicinity tor "share/tor/geoip6")
                              (in-vicinity lib "TorBrowser/Data/Tor/geoip6"))
-                  ;; Fonts
-                  (copy-recursively (in-vicinity
-                                     #$torbrowser-assets "fontconfig")
-                                    (in-vicinity lib "fontconfig"))
-                  (substitute* (in-vicinity lib "fontconfig/fonts.conf")
-                    (("<dir>fonts</dir>")
-                     (format #f "<dir>~a</dir>" (in-vicinity lib "fonts"))))
-                  (delete-file-recursively (in-vicinity lib "fonts"))
-                  (copy-recursively (in-vicinity #$torbrowser-assets "fonts")
-                                    (in-vicinity lib "fonts")))))
+                  (copy-file (in-vicinity tor "share/tor/geoip")
+                             (in-vicinity lib "TorBrowser/Data/Tor/geoip")))))
             (replace 'build-sandbox-whitelist
               (lambda* (#:key inputs #:allow-other-keys)
                 (define (runpath-of lib)
@@ -773,8 +783,8 @@ (define-public torbrowser
                       (display whitelist-string))))))
             (add-after 'install 'autoconfig
               (lambda* (#:key inputs #:allow-other-keys)
-                (let ((lib (in-vicinity #$output "lib/torbrowser"))
-                      (config-file "tor-browser.cfg"))
+                (let ((lib (string-append #$output "/lib/" #$moz-app-name))
+                      (config-file (string-append #$moz-app-name ".cfg")))
                   (with-output-to-file (in-vicinity
                                         lib "defaults/pref/autoconfig.js")
                     (lambda ()
@@ -786,13 +796,6 @@ (define-public torbrowser
                   (with-output-to-file (in-vicinity lib config-file)
                     (lambda ()
                       (format #t "// first line must be a comment~%")
-                      (format #t "pref(~s, ~s);~%"
-                              "extensions.torlauncher.torrc-defaults_path"
-                              (in-vicinity
-                               lib "TorBrowser/Data/Tor/torrc-defaults"))
-                      (format #t "pref(~s, ~s);~%"
-                              "extensions.torlauncher.tor_path"
-                              (search-input-file inputs "bin/tor"))
                       ;; Required for Guix packaged extensions
                       ;; SCOPE_PROFILE=1, SCOPE_APPLICATION=4, SCOPE_SYSTEM=8
                       ;; Default is 5.
@@ -821,64 +824,40 @@ (define-public torbrowser
                       (format #t "pref(~s, ~s);~%"
                               "lightweightThemes.getMoreURL"
                               "https://gnuzilla.gnu.org/mozzarella"))))))
-            (replace 'wrap-program
+            (add-after 'autoconfig 'autoconfig-tor
               (lambda* (#:key inputs #:allow-other-keys)
-                (let* ((gtk #$(this-package-input "gtk+"))
-                       (gtk-share (string-append gtk "/share"))
-                       (fonts.conf (in-vicinity
-                                    #$output
-                                    "lib/torbrowser/fontconfig/fonts.conf"))
-                       (ld-libs '#$(cons
-                                    (file-append
-                                     (this-package-input "libcanberra")
-                                     "/lib/gtk-3.0/modules")
-                                    (map
-                                     (lambda (label)
-                                       (file-append
-                                        (this-package-input label) "/lib"))
-                                     '("libpng-apng"
-                                       "libxscrnsaver"
-                                       "mesa"
-                                       "pciutils"
-                                       "mit-krb5"
-                                       "eudev"
-                                       "pulseaudio"
-                                       "libnotify")))))
-                  (wrap-program
-                      (in-vicinity #$output "lib/torbrowser/torbrowser")
-                    `("XDG_DATA_DIRS" prefix (,gtk-share))
-                    `("LD_LIBRARY_PATH" prefix ,ld-libs)
+                (let ((lib (in-vicinity #$output "lib/torbrowser"))
+                      (config-file (string-append #$moz-app-name ".cfg")))
+                  (let ((port (open-file (in-vicinity lib config-file) "a")))
+                    (format port "pref(~s, ~s);~%"
+                            "extensions.torlauncher.torrc-defaults_path"
+                            (in-vicinity
+                             lib "TorBrowser/Data/Tor/torrc-defaults"))
+                    (format port "pref(~s, ~s);~%"
+                            "extensions.torlauncher.tor_path"
+                            (search-input-file inputs "bin/tor"))
+                    (close port)))))
+            (add-after 'wrap-program 'wrap-fonts
+              (lambda _
+                (let ((fonts.conf (format #f "~a/lib/~a/fontconfig/fonts.conf"
+                                          #$output #$moz-app-name)))
+                  (wrap-program (format #f "~a/lib/~a/~a"
+                                        #$output
+                                        #$moz-app-name #$moz-app-name)
                     `("FONTCONFIG_FILE" prefix (,fonts.conf))))))
             (replace 'install-desktop-entry
               (lambda _
                 (let ((apps (in-vicinity #$output "share/applications")))
                   (mkdir-p apps)
                   (make-desktop-entry-file
-                   (in-vicinity apps "torbrowser.desktop")
-                   #:name "Tor Browser"
-                   #:exec
-                   (format #f "~a %u" (in-vicinity #$output "bin/torbrowser"))
-                   #:comment
-                   "Tor Browser is +1 for privacy and -1 for mass surveillance"
+                   (string-append apps #$moz-app-name ".desktop")
+                   #:name #$moz-app-remotingname
+                   #:exec (format #f "~a/bin/~a %u" #$output #$moz-app-name)
                    #:categories '("Network" "WebBrowser" "Security")
-                   #:startup-w-m-class "Tor Browser"
-                   #:icon "tor-browser"))))
-            (replace 'install-icons
-              (lambda* (#:key inputs #:allow-other-keys)
-                (for-each
-                 (lambda (size)
-                   (let ((oldpath (string-append
-                                   "browser/branding/tb-release/default"
-                                   size ".png"))
-                         (newpath (string-append #$output
-                                                 "/share/icons/hicolor/"
-                                                 size "x" size "/apps")))
-                     (mkdir-p newpath)
-                     (copy-file oldpath
-                                (in-vicinity newpath "tor-browser.png"))))
-                 '("16" "22" "24" "32" "48" "64" "128" "256"))))))))
+                   #:startup-w-m-class #$moz-app-remotingname
+                   #:icon #$moz-app-name))))))))
     (inputs
-     (modify-inputs (package-inputs icecat-minimal)
+     (modify-inputs (package-inputs base)
        (append go-gitlab-torproject-org-tpo-anti-censorship-pluggable-transports-lyrebird
                tor-client)))
     (propagated-inputs
@@ -892,3 +871,11 @@ (define-public torbrowser
 attacks on the privacy of Tor users.")
     (license license:mpl2.0)))       ;And others, see
                                      ;toolkit/content/license.html
+
+(define-public torbrowser
+  (make-torbrowser #:moz-app-name "torbrowser"
+                   #:moz-app-remotingname "Tor Browser"
+                   #:branding-directory "browser/branding/tb-release"
+                   #:assets torbrowser-assets
+                   #:locales %torbrowser-locales
+                   #:base-browser-version %torbrowser-version))
