Your local (not available system-wide) default applications list is defined in this file: ~/.config/mimeapps.list
Inside that file, you will typically see something like this:
[Default Applications]
application/pdf=someapplicationname.desktop
image/jpeg=someapp.desktop
..
..
Internally, pre-defined mime types (image/jpeg, application/pdf, etc.) are stored in databases (~/.local/share/mime and /usr/share/mime). These databases are essentially directories with a certain structure containing a bunch of files.
You can even define your own mime type by creating an xml file specifying the properties of the new mimetype and then manually update your mime database with cli tools.
For instance, here is a mimetype I created for my own use: application/cherrytree
I first create an xml (application-cherrytree.xml) inside ~/.local/share/mime/packages (it’s important for the xml file to be placed in this directory so that the tools I mention later can find it). That xml file has the following content:
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/cherrytree">
<comment>Cherry Tree Note</comment>
<glob-deleteall/>
<glob pattern="*.ctb"/>
</mime-type>
</mime-info>
The xml file provides sufficient information for mime tools to be able to “detect” and “identify” the application/cherrytree mime type. If you look at the contents of the xml file, you can already guess what it does: it tells the mime utilities to associate any file with the extension .ctb as a application/cherrytree type.
At this point, although I have written the xml file, the mime system still doesn’t know about my new mime type yet. I have to register it inside the mimetype database. The shared-mime-info package provides a command line tool called update-mime-database to do just that. If you run this command:
$ update-mime-database
What happens is that it will look for all the .xml files inside ~/.local/share/mime/packages and check whether the mime types defined in those .xml files are already registered inside the mime databases. In our example, the application/cherrytree mime type is newly defined (it is not yet registered), so update-mime-database will add it into database by parsing the specifications contained inside application-cherrytree.xml.
After the new mime type has been registered, the final step is to associate .desktop files with it. Application packages typically ship with their own .desktop files (look inside /usr/share/applications if you’re curious). These associations are entered inside the ~/.config/mimeapps.list file I mentioned previously.
For more information, refer to https://wiki.archlinux.org/title/XDG_MIME_Applications
The article has all the details.