diff --git a/doc/WhatsNew.rst b/doc/WhatsNew.rst
index 7ed0d9ea2..6ce29cc83 100644
--- a/doc/WhatsNew.rst
+++ b/doc/WhatsNew.rst
@@ -22,6 +22,8 @@ Ver 5.0.0 (unreleased)
 - Updates for deprecations in numpy 2.0
 - Fix for missing menubar on some versions of Qt and Mac OS X
 - Fix for importing mpl colormaps with recent versions of matplotlib
+- Added LoaderConfig plugin; allows setting of loader priorities for
+  various MIME types
 
 Ver 4.1.0 (2022-06-30)
 ======================
diff --git a/doc/manual/plugins.rst b/doc/manual/plugins.rst
index ee17055fa..d3e88650e 100644
--- a/doc/manual/plugins.rst
+++ b/doc/manual/plugins.rst
@@ -52,6 +52,7 @@ Global plugins
    plugins_global/command
    plugins_global/saveimage
    plugins_global/downloads
+   plugins_global/loaderconfig
 
 
 .. _sec-localplugins:
diff --git a/doc/manual/plugins_global/figures/loaderconfig-plugin.png b/doc/manual/plugins_global/figures/loaderconfig-plugin.png
new file mode 100644
index 000000000..036c07d19
Binary files /dev/null and b/doc/manual/plugins_global/figures/loaderconfig-plugin.png differ
diff --git a/doc/manual/plugins_global/loaderconfig.rst b/doc/manual/plugins_global/loaderconfig.rst
new file mode 100644
index 000000000..82840c9e1
--- /dev/null
+++ b/doc/manual/plugins_global/loaderconfig.rst
@@ -0,0 +1,13 @@
+.. _sec-plugins-LoaderConfig:
+
+LoaderConfig
+============
+
+.. image:: figures/loaderconfig-plugin.png
+   :align: center
+   :width: 800px
+   :alt: LoaderConfig plugin
+
+.. automodapi:: ginga.rv.plugins.LoaderConfig
+   :no-heading:
+   :skip: LoaderConfig
diff --git a/ginga/rv/main.py b/ginga/rv/main.py
index 588347f91..191d44d9e 100644
--- a/ginga/rv/main.py
+++ b/ginga/rv/main.py
@@ -19,7 +19,7 @@
 from ginga.misc import Task, ModuleManager, Settings, log
 import ginga.version as version
 import ginga.toolkit as ginga_toolkit
-from ginga.util import paths, rgb_cms, json, compat
+from ginga.util import paths, rgb_cms, json, compat, loader
 
 # Catch warnings
 logging.captureWarnings(True)
@@ -168,6 +168,9 @@
           menu="Header [G]", hidden=False, category='Utils', ptype='global'),
     Bunch(module='Zoom', tab='Zoom', workspace='left', start=False,
           menu="Zoom [G]", category='Utils', ptype='global'),
+    Bunch(module='LoaderConfig', tab='Loaders', workspace='channels',
+          start=False, menu="LoaderConfig [G]", category='Debug',
+          ptype='global'),
 ]
 
 
@@ -518,6 +521,26 @@ def main(self, options, args):
         guiHdlr.setFormatter(fmt)
         logger.addHandler(guiHdlr)
 
+        # Set loader priorities, if user has saved any
+        # (see LoaderConfig plugin)
+        path = os.path.join(self.basedir, 'loaders.json')
+        if os.path.exists(path):
+            try:
+                with open(path, 'r') as in_f:
+                    loader_dct = json.loads(in_f.read())
+
+                # set saved priorities for openers
+                for mimetype, m_dct in loader_dct.items():
+                    for name, l_dct in m_dct.items():
+                        opener = loader.get_opener(name)
+                        loader.add_opener(opener, [mimetype],
+                                          priority=l_dct['priority'],
+                                          note=opener.__doc__)
+
+            except Exception as e:
+                self.logger.error(f"failed to process loader file '{path}': {e}",
+                                  exc_info=True)
+
         # Load any custom modules
         if options.modules is not None:
             modules = options.modules.split(',')
diff --git a/ginga/rv/plugins/LoaderConfig.py b/ginga/rv/plugins/LoaderConfig.py
new file mode 100644
index 000000000..afc0eeaf7
--- /dev/null
+++ b/ginga/rv/plugins/LoaderConfig.py
@@ -0,0 +1,173 @@
+# This is open-source software licensed under a BSD license.
+# Please see the file LICENSE.txt for details.
+"""
+The ``LoaderConfig`` plugin allows you to configure the file openers that
+can be used to load various content into Ginga.
+
+Registered file openers are associated with file MIME types, and there can
+be several openers for a single MIME type.  A priority associated
+with a MIME type/opener pairing determines which opener will be used
+for each type--the lowest priority value will determine which opener will
+be used.  If there are more than one opener with the same low priority
+then the user will be prompted for which opener to use, when opening a
+file in Ginga.  This plugin can be used to set the opener preferences
+and save it to the user's $HOME/.ginga configuration area.
+
+**Plugin Type: Global**
+
+``LoaderConfig`` is a global plugin.  Only one instance can be opened.
+
+**Usage**
+
+After starting the plugin, the display will show all the registered MIME
+types and the openers registered for those types, with an associated
+priority for each MIME type/opener pairing.
+
+Select one or more lines and type a priority for them in the box labeled
+"Priority:"; press "Set" (or ENTER) to set the priority of those items.
+
+.. note:: The lower the number, the higher the priority. Negative numbers
+          are fine and the default priority for a loader is usually 0.
+          So, for example, if there are two loaders available for a MIME
+          type and one priority is set to -1 and the other to 0, the one
+          with -1 will be used without asking the user to choose.
+
+
+Click "Save" to save the priorities in your $HOME/.ginga area so that they
+will be reloaded and used on subsequent restarts of the program.
+"""
+import os.path
+
+from ginga import GingaPlugin
+from ginga.util.paths import ginga_home
+from ginga.util import loader, json
+from ginga.gw import Widgets
+
+__all__ = ['LoaderConfig']
+
+
+class LoaderConfig(GingaPlugin.GlobalPlugin):
+
+    def __init__(self, fv):
+        super().__init__(fv)
+
+        self.loader_dct = dict()
+
+        self.columns = [("Name", 'name'),
+                        ("Priority", 'priority'),
+                        ("Note", 'note')]
+
+        self.gui_up = False
+
+    def build_gui(self, container):
+        vbox = Widgets.VBox()
+        vbox.set_spacing(1)
+
+        tv = Widgets.TreeView(sortable=True, use_alt_row_color=True,
+                              selection='multiple', auto_expand=True)
+        tv.add_callback('selected', self.select_cb)
+        tv.setup_table(self.columns, 2, 'name')
+        self.w.loader_tbl = tv
+
+        vbox.add_widget(tv, stretch=1)
+
+        tbar = Widgets.HBox()
+        tbar.set_border_width(4)
+        tbar.set_spacing(4)
+
+        tbar.add_widget(Widgets.Label('Priority:'))
+        pri = Widgets.TextEntrySet(editable=True)
+        pri.set_tooltip("Edit priority of loader (lower=better, negative numbers ok)")
+        pri.set_enabled(False)
+        pri.add_callback('activated', self.set_priority_cb)
+        self.w.pri_edit = pri
+        tbar.add_widget(pri)
+
+        tbar.add_widget(Widgets.Label(''), stretch=1)
+        vbox.add_widget(tbar, stretch=0)
+
+        btns = Widgets.HBox()
+        btns.set_border_width(4)
+        btns.set_spacing(4)
+
+        btn = Widgets.Button("Close")
+        btn.add_callback('activated', lambda w: self.close())
+        btns.add_widget(btn)
+        btn = Widgets.Button("Help")
+        btn.add_callback('activated', lambda w: self.help())
+        btns.add_widget(btn, stretch=0)
+        btn = Widgets.Button("Save")
+        btn.add_callback('activated', lambda w: self.save_loaders_cb())
+        btn.set_tooltip("Save configuration of loaders")
+        btns.add_widget(btn, stretch=0)
+
+        btns.add_widget(Widgets.Label(''), stretch=1)
+        vbox.add_widget(btns, stretch=0)
+        container.add_widget(vbox, stretch=1)
+
+        self.gui_up = True
+
+    def start(self):
+        # create loader table
+        tree_dct = dict()
+        for mimetype, dct in loader.loader_by_mimetype.items():
+            md = dict()
+            tree_dct[mimetype] = md
+            for name, bnch in dct.items():
+                md[name] = dict(name=bnch.opener.name,
+                                priority=bnch.priority,
+                                note=bnch.opener.note)
+            self.loader_dct = tree_dct
+
+        self.w.loader_tbl.set_tree(self.loader_dct)
+        self.w.loader_tbl.set_optimal_column_widths()
+
+    def stop(self):
+        self.gui_up = False
+
+    def set_priority_cb(self, w):
+        sel_dct = self.w.loader_tbl.get_selected()
+        priority = int(self.w.pri_edit.get_text())
+        for mimetype, ld_dct in sel_dct.items():
+            for name, m_dct in ld_dct.items():
+                self.loader_dct[mimetype][name]['priority'] = priority
+                # actually change it in the loader registration
+                opener = loader.get_opener(name)
+                loader.add_opener(opener, [mimetype], priority=priority,
+                                  note=opener.__doc__)
+        # update the UI table
+        self.w.loader_tbl.set_tree(self.loader_dct)
+
+    def save_loaders_cb(self):
+        path = os.path.join(ginga_home, 'loaders.json')
+        try:
+            with open(path, 'w') as out_f:
+                out_f.write(json.dumps(self.loader_dct, indent=4))
+
+        except Exception as e:
+            self.logger.error(f"failed to save loader file: {e}",
+                              exc_info=True)
+            self.fv.show_error(str(e))
+
+    def select_cb(self, w, dct):
+        selected = len(dct) > 0
+        self.w.pri_edit.set_enabled(selected)
+        if not selected:
+            self.w.pri_edit.set_text('')
+        else:
+            # only set priority widget if all selected are the same
+            # unique value
+            priorities = set([l_dct['priority']
+                              for m_dct in dct.values()
+                              for l_dct in m_dct.values()])
+            if len(priorities) == 1:
+                self.w.pri_edit.set_text(str(priorities.pop()))
+            else:
+                self.w.pri_edit.set_text('')
+
+    def close(self):
+        self.fv.stop_global_plugin(str(self))
+        return True
+
+    def __str__(self):
+        return 'loaderconfig'
diff --git a/ginga/util/io/io_fits.py b/ginga/util/io/io_fits.py
index e34b0fa64..391aa5f43 100644
--- a/ginga/util/io/io_fits.py
+++ b/ginga/util/io/io_fits.py
@@ -220,7 +220,7 @@ class AstropyFitsFileHandler(BaseFitsFileHandler):
     """
 
     name = 'astropy.io.fits'
-    mimetypes = ['image/fits', 'image/x-fits']
+    mimetypes = ['image/fits', 'image/x-fits', 'application/fits']
 
     @classmethod
     def check_availability(cls):
@@ -562,7 +562,7 @@ class FitsioFileHandler(BaseFitsFileHandler):
     """For loading FITS (Flexible Image Transport System) data files.
     """
     name = 'fitsio'
-    mimetypes = ['image/fits', 'image/x-fits']
+    mimetypes = ['image/fits', 'image/x-fits', 'application/fits']
 
     @classmethod
     def check_availability(cls):