I’ve been a long-time Firefox user – for over ten years at this point. I’ve amassed thousands of bookmarks, some of which I have spent time organizing and tagging. As such, lately I was thinking I really should set up some sort of backup system, but I had trouble locating any commands or scripts that could accomplish this.
If you want to jump right to the solutions section, click here, otherwise read on.
Find Your Profile Folder
Pretty much all of your data in Firefox is stored in your profile folder. This is a special folder, whose location is unique to your computer due to its use of profile IDs and OS user directories.
This is the definitive documentation on how to find this folder location.
If you have the basic *nix utilities installed, you can use this one-liner to get the path on Windows:
tail "%APPDATA%\Mozilla\Firefox\profiles.ini" -n +2 | head -n 1 | sed -E 's/Default=//' | xargs -I % echo "%APPDATA%\Mozilla\Firefox\%" | sed -E 's/\//\\\/g'
# Example: "C:\Users\Joshua\AppData\Roaming\Mozilla\Firefox\Profiles\29adfe2f.default-release"
Research
First, let’s investigate how Firefox stores user bookmarks.
The best place to get this information is the Mozilla support page – “Where Firefox Stores User Data”. I’ll supplement this with some additional details below.
Some key things to note, which affect our task:
- Bookmarks are contained in
place.sqlite
, along with download metadata and browsing history- This makes extraction more difficult, as this is a special database, can you can’t easily copy & paste out of it, or view it, or easily import it into Firefox or other browsers
- This will be the most up-to-date stored version of your bookmarks, as the automated backup options (see below) either run periodically, or when the browser shuts down. In comparison,
places.sqlite
is updated in almost real-time as you edit bookmarks in Firefox.
- There are some automated backup options, which essentially output a subset of
places.sqlite
, with just the bookmarks./Profiles/{PROFILE_ID}/bookmarkbackups
should contain daily backups of bookmarks- However, these are stored in a somewhat obscure
.jsonlz4
file type, which is JSON compressed with a flavor of theLZ4
algorithm
- However, these are stored in a somewhat obscure
- By changing the config value (in
about:config
) ofbrowser.bookmarks.autoExportHTML
totrue
, you can have Firefox automatically dump a backup of the bookmarks in HTML format, on browser close.- You can control the file location with config value
browser.bookmarks.file
- See this post for details
- You can control the file location with config value
Converting the .jsonlz4
Bookmarks File(s)
Note: You don’t need to convert the files if all you want them for is a backup that you can re-import into Firefox; Firefox understands this file format and will let you use it as an import, no conversion required.
The bookmarkbackups
folder and its .jsonlz4
daily backup files are a nice existing backup to take advantage of, but how can we get the files in plain JSON, so we can do whatever we want with their contents (convert to CSV, cleanup, etc.).
Existing options (found via a quick Google search):
- Everything listed in this thread
- Online tool: Jefferson Scher: “BookBackReader”
- Offline tools:
- C / Binary release: avih/dejsonlz4
- NodeJS / CLI: thrilleratplay/node-jsonlz4-decompress
- Python: TBlue Github Gist
Solutions
Manual Methods
For manual bookmark exporting, there are some nice built-in options. These are covered here, but to summarize:
- Open the Bookmark Library (
CTRL + SHIFT + B
, or use Library Button in toolbar) - Open the
Import and Backup
menu - Use either of:
Backup
- this exports a
UTF-8
JSON file, which is not compressed withlz4
– you can open and read this file easily
- this exports a
Export Bookmarks to HTML
- This exports a HTML file, which you can easily open with any standard web browser
- The downside is that it is roughly 2x the size of the JSON export, and would be harder to parse if you wanted to automate the transformation of your bookmarks into another format
Also, if you don’t care about backing them up to a specific folder, than using the default automated backups (discussed above, here), might be enough for you.
Automated Methods
For putting together a command / script to grab a Bookmarks backup, I have three main options:
- Hook into the internals of Firefox
- The best place would be the
BookmarkJSONUtils.jsm
utility – this has a native method for exporting to JSON –exportToFile
- You can actually get to this in the browser, with
resource://gre/modules/BookmarkJSONUtils.jsm
- You can actually get to this in the browser, with
- Although this would probably be the most “to-spec” option, it would also take me a while to figure out how to do, especially given some limitations around scripting Firefox
- For example, the
headless mode
of Firefox might let meeval()
JS to extract the bookmarks, but you cannot concurrently use that and have an open instance of Firefox with the profile you want to use
- For example, the
- The best place would be the
- Connect to the
places.sqlite
database and extract just the bookmarks, converting on-the-fly to JSON or HTML- Complicated, and might have issues around concurrent db access
- Just grab the daily backups (
.jsonlz4
files) and copy to backup folder of choice- This is, by far, the easiest option.
- I’ve implemented this below
Automated Methods – Batch Script
I’m not thrilled with it, but here is a batch file I put together to copy the most recent JSON file to my Dropbox. It requires that some standard *nix utilities are installed (these come default with git-bash), and unfortunately, you have to hard-code the backup folder(s). But, it works!
ff-bookmarks-backup.bat
:
@REM # Hard-coded paths - EDIT ME
SET FF_DAILY_BACK_FOLDER="C:\Users\Joshua\AppData\Roaming\Mozilla\Firefox\Profiles\29adfe2f.default-release\bookmarkbackups"
SET OUTPUT_FOLDER="C:\Users\Joshua\Dropbox\Program Settings"
@REM # Remove quotes, as these are going to mess up paths later
SET FF_DAILY_BACK_FOLDER=%FF_DAILY_BACK_FOLDER:"=%
SET OUTPUT_FOLDER=%OUTPUT_FOLDER:"=%
@REM # Go to bookmarks folder
cd %FF_DAILY_BACK_FOLDER%
@REM # Workaround to capture variable that requires *nix utils
ls | tail -n 1 > backup_filename
for /f %%i in ('cat backup_filename') do set LATEST_BACKUP_FILEPATH=%%i
SET LATEST_BACKUP_FILEPATH=%FF_DAILY_BACK_FOLDER%\%LATEST_BACKUP_FILEPATH%
echo %LATEST_BACKUP_FILEPATH%
@REM # Copy file with rename
@REM # NOTE: This will overwrite, keeping a single file up to date with latest
cp "%LATEST_BACKUP_FILEPATH%" "%OUTPUT_FOLDER%\ff-bookmarks-latest.jsonlz4"
@REM # Cleanup
rm backup_filename
Automated Methods – A Better Solution
If I had a lot more free time, and wanted this badly enough, I would code this as a NodeJS script, and compile it to a portable binary using something like vercel/pkg. If this is something you are interested in doing so yourself, my advice would be to have the script:
- Parse OS environmental variables and paths to find the Firefox user profile folder
- Find the most recent file in the folder
- Decompress it using thrilleratplay/node-jsonlz4-decompress
- Copy the raw and de-decompress versions to the output directly, specified by the user through a CLI argument
- Having the tool copy both versions to output could be made optional