Back to blog

How to Export Your Snippets from SnippetsLab

5 min read·snippetslab, migration, backup

Whether you are switching apps, setting up a second Mac, or just want a copy of your library that does not depend on one piece of software, it is worth knowing how to get your snippets out of SnippetsLab — and what you actually get when you do.

This guide covers both export formats, what is inside them, and how to read them yourself. It is useful whether or not you end up moving anywhere.

The two formats

SnippetsLab can produce two things, and they are not interchangeable.

A backup (.snippetslab-backup) is the complete library: snippets, folders, tags, attachments, and internal metadata. It is what you want for a full migration or a real archive.

A JSON export (.json) is a more readable dump of the library contents, alongside an attachments folder.

Both are created from SnippetsLab's own export or backup commands in the app.

The thing that confuses everyone

Both formats are directory packages, not files.

A macOS package is a folder that Finder displays as a single item. So MyLibrary.snippetslab-backup looks like one file, but it is a directory with a structure inside. The same is true of the .json export — despite the extension, it is a folder containing a JSON file and an Attachments/ directory, not a single JSON document.

This trips people up in two ways. Scripts that try to open the export as a JSON file fail, because it is a directory. And file pickers that filter by type often grey the export out entirely, because the package's type is not what the picker expects.

To look inside: right-click the item in Finder and choose Show Package Contents. Or from a terminal, just cd into it — the shell has never cared about the packaging illusion.

What is actually inside

A backup looks roughly like this:

MyLibrary.snippetslab-backup/
├── library.json                       # the whole library, readable JSON
├── meta.json                          # backup metadata
└── main.snippetslablibrary/
    └── Database/
        ├── Snippets/{UUID}.data       # binary plists, one per snippet
        ├── Attachments/{filename}     # attachment files
        ├── folders.data               # binary plist, folder tree
        └── tags.data                  # binary plist, tags

The useful discovery: library.json contains essentially everything in plain, readable JSON. Snippets, their contents, folders, and tags are all there. If you want your data in a portable form, that one file is the answer, and you can read it with anything.

The .data files are binary property lists in NSKeyedArchiver format, which is a much less pleasant thing to parse — it is an object graph with a $objects array and CF$UID cross-references rather than a straightforward tree. You mostly do not need them, with one significant exception below.

A JSON export is simpler:

SnippetsLab (date).json/
├── SnippetsLab (date).json            # same shape as library.json
└── Attachments/                       # attachment files

Two details worth knowing before you rely on this

Folder and tag assignments are not in library.json. This is the awkward one. The snippet contents and the list of folders and tags are in the JSON, but which snippet belongs to which folder, and which tags are on it, live in those binary .data files under Snippets/, as SnippetFolderUUID and SnippetTagUUIDs keys.

So a naive script that reads only library.json gets all your snippets and all your folders — and drops the relationship between them, flattening your organisation. If you are writing your own migration, that is the part to get right. If you are using someone's importer, it is worth checking whether they did.

A snippet can hold several fragments. In SnippetsLab a snippet is a container, and each fragment inside it has its own language and content. That is a genuinely different model from apps that treat one snippet as one piece of code, and any export or import has to decide what to do with it. A reasonable mapping is to keep the first fragment as the snippet and attach the rest as linked files, so nothing is lost.

Attachments are referenced from snippet content with SnippetsLab's own syntax, something like #![name](file:///.attachment/UUID.png), pointing at the files in Attachments/. If you move the text somewhere else without rewriting those links, the images break.

Reading it yourself

Since library.json is ordinary JSON, a look at your own library is a one-liner:

cd ~/path/to/MyLibrary.snippetslab-backup
python3 -c "import json; d=json.load(open('library.json')); print(len(d.get('snippets', [])), 'snippets')"

Keeping a copy of that file somewhere safe is, honestly, a reasonable backup strategy on its own — independent of any app, readable in ten years, greppable today.

Importing into SnipperApp 3

If you are moving to SnipperApp 3, both formats import directly — including the folder and tag relationships from those binary files, and the attachments.

  1. File → Import from SnippetsLab...
  2. Select the .snippetslab-backup or the .json export.
  3. Multi-fragment snippets arrive as linked files, attachments are copied in, and their links are rewritten so images keep working.

There is a skip duplicates option in Settings → Backup, on by default, so re-importing an overlapping export will not give you two of everything.

Your SnippetsLab library is untouched by any of this. Export is non-destructive, the import only reads, and nothing stops you running both apps while you decide.

If you want to know what you would be moving to: SnipperApp 3 is a one-time purchase with a 7-day trial and no subscription, and it can expose your library to Claude and Cursor over MCP — which is the main thing it does that other snippet managers currently do not.