---
title: "Working with OPML — freefeed"
url: "https://freefeed.app/en/guide/opml"
lang: "en"
description: "OPML is the format for carrying a subscription list to another service. You can check what it does and does not contain before you switch."
updated: "2026-09-15"
---

# Working with OPML

OPML is the format for carrying a subscription list to another service. You can check what it does and does not contain before you switch.

## What it contains

OPML carries the subscription list and folder structure, and nothing else.

- Feed URLs and titles
- Folder (category) structure
- Site URLs, sometimes

## What the file looks like

An OPML file is plain text. The extension is usually .opml, but the contents are XML, so you can open it in any text editor and read it.

Each subscription is a single outline element, roughly one line of outline text="Site name" xmlUrl="https://example.com/feed" htmlUrl="https://example.com/" type="rss".

- xmlUrl — the feed URL itself. This is what a subscription actually is; a line without it is not treated as a feed
- text / title — the name your reader displays. Sometimes both are present, sometimes only one
- htmlUrl — the site home page. Imports work fine without it
- type — almost always rss, including for feeds that are actually Atom

## How folders are represented

An outline without an xmlUrl is a folder, with child outlines nested inside it. Folders and feeds are the same element; the presence of xmlUrl is the only thing that separates them.

This is the part that most often breaks in a move. If the service you exported from used folders three or more levels deep, an importer that cannot handle that depth will either drop the folders or flatten everything to the top level.

freefeed folds anything deeper than two levels into two. The first folder name becomes the parent, and everything below it is joined into a single name like "child/grandchild", so where a feed used to live is still readable.

## What it does not

Read state, stars, tags and rules are not included. That is not a restriction imposed by any particular service — the format simply has no field for them.

So read state never transfers, whichever direction you move. Marking everything read once after importing is the practical approach.

## How to export

From the major services:

- Inoreader: Preferences → Import/Export → Export subscriptions
- Feedly: Organize sources → Export OPML
- FreshRSS: Settings → Import/export → Export OPML
- The Old Reader: Settings → Import/Export

## Check it before importing

A subscription list built over years accumulates dead feeds and duplicates. Looking at it first means you do not carry them across.

There is a tool here that shows you the contents of an OPML file entirely in your browser. The file is never uploaded.

If you import while signed in, you get a list that has been checked entry by entry first. Feeds you already follow, feeds that have stopped updating and feeds that can no longer be fetched are marked, and the duplicates and stopped ones arrive with their checkboxes already cleared. Carry on and they simply are not imported.

## Where imports go wrong

When an import does not do what you expected, it is usually one of these.

- The file is over 5MB — it will not be accepted. That is a limit on file size, not on the number of feeds
- More than 1,000 subscriptions — the first 1,000 are taken
- More than 100 folders — the folders past that are not created, and those feeds land unsorted
- The same feed exported twice — some services write a separate outline for starred or favourite items, so one URL appears on two lines. The second one is flagged as a duplicate in the check list
- A broken export with no xmlUrl anywhere — everything is treated as a folder and no feeds come through. Open it in a text editor and look for xmlUrl

## What happens with long lists

An import splits into what is handled immediately and what is handled afterwards. The first 50 feeds go in when you press the button; the rest are queued and processed in the background.

So with a long list, not everything is there right after importing. It fills in as the queue drains, and you can close the page meanwhile. Fetching the articles comes after that again, so it takes a little while before the first articles appear.

## What to do afterwards

Since read state cannot come with you, a few things are worth doing right after a move.

- Mark everything read once — so you do not start with years of unread already stacked up
- Rebuild your rules and filters — they are not in the OPML, so they have to be created again
- Drop the feeds that error — lists often contain sites that disappeared years ago

## A note on exporting

An OPML exported from freefeed also contains only the subscription list and the folder structure. Favourite marks are not in it.

That is a constraint of the format. OPML describes a tree of folders, and it has no standard attribute for a mark that cuts across the tree. Writing a separate favourites outline would put the same feed in the file twice, which becomes a double subscription wherever you import it.

Everything including favourites is in the data-export JSON you can download from settings, so nothing is actually lost.

## FAQ

### Is my OPML file uploaded anywhere?

No. The tool that shows its contents runs entirely in your browser; the file is never sent to a server.

### Does read state carry over?

No. Read state, stars and tags have no field in the OPML format itself.

### Are folders preserved?

Yes, though anything deeper than two levels is folded into two. The first level becomes the parent and everything below it is joined into a single name like "child/grandchild", so where a feed used to sit is still legible.

### Can I edit an OPML by hand?

Certainly. It is a text file, so deleting lines is a fine way to narrow down what gets imported. Just delete whole lines — removing only the xmlUrl attribute turns that line into a folder.

### Are there size or count limits?

Files up to 5MB, 1,000 subscriptions, and 100 folders. Hitting a limit only means the excess is not imported; it does not fail the whole thing.

### Can I import OPMLs from several services at once?

Import them one after another. From the second file on, feeds you already follow are flagged as duplicates and unchecked by default, so nothing is subscribed twice.

### It imported, but there are no articles

Articles have not been fetched yet right after the subscriptions land. Fetching is queued separately from subscribing, so give it a little time. If nothing appears at all after that, the feed itself may have stopped publishing.

## Other guides

- [What is RSS?](https://freefeed.app/en/guide/what-is-rss)
- [Finding feeds](https://freefeed.app/en/guide/find-feeds)
- [RSS, Atom and JSON Feed](https://freefeed.app/en/guide/feed-formats)
- [When a feed stops updating](https://freefeed.app/en/guide/feed-not-updating)
- [Moving your subscriptions from Feedly](https://freefeed.app/en/guide/feedly-migration)
- [Moving your subscriptions from Inoreader](https://freefeed.app/en/guide/inoreader-migration)
- [Following a YouTube channel by RSS](https://freefeed.app/en/guide/youtube-rss)
- [Following note and Hatena Blog by RSS](https://freefeed.app/en/guide/note-hatena-rss)
- [Following a site that has no RSS feed](https://freefeed.app/en/guide/html-to-feed)
- [Cutting the backlog with rules and filters](https://freefeed.app/en/guide/rss-filter-rules)
- [What a cloud RSS reader is](https://freefeed.app/en/guide/rss-reader-cloud)
- [Using freefeed from an AI agent](https://freefeed.app/en/guide/ai-agents)
- [RSS glossary](https://freefeed.app/en/guide/glossary)
