Codingfish Skip to content

What imports from what

The question that decides whether a move is a weekend or a quarter. Here it is answered from the projects' own repositories rather than from memory — and where it cannot be, it says so.

Every platform claims migration is possible. What matters is whether somebody has already written and maintained the code that does it, because the alternative is that you write it — against two undocumented schemas, one of which you are about to retire.

Discourse is the outlier here, and it is worth being precise about why. Its importers are ordinary files in its repository, one per source platform, which means the list can be read rather than asserted. On 2026-09-02 that directory held 63 scripts covering 45 identifiable sources.

Which forum platforms Discourse ships an importer for: 7 of the 10 other forum platforms in the catalogue are covered; NodeBB, Misago and Talkyard are not.
An importer existing is not the same as a migration being easy — but its absence is a real cost.

Into Discourse, from platforms in this catalogue

Read from the project's own importer directory on 2026-09-02.

FromImporter script
Flarum flarum_import
Invision Community ipboard, ipboard3
MyBB mybb, mybbru
Question2Answer question2answer
Simple Machines Forum smf1, smf2
Vanilla vanilla, vanilla_body_parser, vanilla_mysql
XenForo xenforo
phpBB phpbb3

8 of the platforms catalogued on this site have a maintained importer into Discourse. A further 37 sources are covered that are not in the catalogue — including AnswerHub, Answerbase, Askbot, Discuz!, Disqus, Drupal and others.

Why this table is one-directional

It would be more useful as a grid — every platform down one side, every platform across the top. That grid is not published here because it cannot be filled honestly.

Discourse enumerates its importers in the open. The other projects do not: their migration tooling lives in separate repositories, in community extensions, or in documentation, and the coverage varies by version in ways a directory listing cannot capture. Filling those cells from general knowledge would produce a table that looks authoritative and misleads in exactly the situation it exists for — someone planning a move.

So the rule applied is narrow: a cell appears when the project ships the code and the code can be pointed at. Everything else is described in prose below, with what to check.

What to establish for any other pair

Four questions, in order, and the first two are usually decisive.

Does an importer exist at all, and who maintains it? Find the repository and look at the date of the last commit against the target platform's last release. An importer two major versions behind is not a migration path; it is a starting point for one. This is the single check that predicts most of the work, and it takes about a minute.

What does it carry? Posts and topics almost always. Users, usually, minus the passwords. Attachments, sometimes. Private messages, categories, permissions and edit history — often not, and rarely stated up front. Ask specifically about the things your community would notice losing.

What happens to the addresses? Importers renumber topics, and a renumbered topic is a new address. If nothing records which old identifier became which new one, every link ever made to that board points at nothing after the cutover. Some importers write the mapping; most do not unless asked. Capture it during the import, because the source database is the only place it exists and it is the first thing decommissioned.

Can it be run twice? A migration that only works on an empty target is a single attempt with no rehearsal. Being able to import into a throwaway instance, look at the result, and start again is the difference between a controlled move and a bad weekend.

Rehearse it, twice

The first import is never the one you keep. It surfaces the encoding problem, the attachment paths that were absolute, the three thousand posts by a deleted account, and the category that existed twice under different names. None of that is visible in the source board, because the source board has been working around it for years.

So run it against a throwaway instance first and read the result rather than the log. Open the longest thread you have, the oldest one, and one with a lot of quoting — those three between them expose most of what breaks. Then throw the instance away and do it again with the fixes, because the second run is the one that tells you how long the real one takes.

Time the second run. A board that imports in twenty minutes can be moved on a quiet evening; a board that takes six hours needs a maintenance window, an announcement, and a decision about what happens to posts written while the import is running. That decision is much easier before the day than during it.

Accounts are the part that loses people

Password hashes rarely survive a migration, which means most moves end with every member resetting a password. A proportion never do, and that proportion is the actual cost of the move — not the hours, which you can plan for.

Three things reduce it. Keep usernames identical, so the reset email is recognisable rather than suspicious. Warn people before rather than after, in the place they already read. And check the sending domain's reputation before the mass reset goes out — a fresh installation sending several hundred password emails on its first day is exactly the pattern spam filters are built to catch, and a community that cannot receive the reset has effectively been closed.

Where the community sits beside an existing site, this is also the moment single sign-on becomes cheap. If accounts have to be touched anyway, moving identity to the main site costs little more than the reset would have, and it removes the duplication permanently. That path is covered in the single sign-on guide.

What to do with the old board

The instinct is to switch it off the moment the new one is live. Keeping it reachable for a few weeks, at a different address and closed to posting, is worth more than the hosting costs.

It is the only place to look something up when an import turns out to have dropped a field, and the only way to answer a member who says a thread is missing — which happens, and is usually about a thread they could not find rather than one that is gone. A read-only original settles both in minutes instead of an afternoon.

What it must not do is stay indexable. Two copies of the same content, both reachable, is a duplicate the search engine resolves in whichever direction it prefers, and it may not prefer yours. Close it to crawlers, keep it for the humans who need it, and retire it once a full month has passed without anyone consulting it.

The direction nobody plans for

Importers are written towards the platform that wants the users. That produces a well-trodden path in and a rough one out, and it is worth noticing which direction you are choosing before the choice is expensive.

Ask what leaving looks like at the point of arriving, not later. A documented export format and at least one maintained importer elsewhere is the difference between adopting software and being adopted by it. This is not paranoia about a project's intentions — it is an observation about where volunteer effort goes, which is towards growth rather than towards exit.

The practical version: before committing, confirm that a full export can be produced by somebody who is not a database administrator, and that at least one other platform can read it. If neither is true, the migration cost is not high — it is unknown, which is worse.

Content that does not survive the schema

Two boards can hold the same conversation and disagree about what a post is. That disagreement is where content quietly changes shape during an import, and it is rarely mentioned because nothing errors.

Markup is the common case. A board that stored BBCode and one that stores Markdown need a translation, and the translation is lossy at the edges: nested quotes, tables written by hand, custom tags a plugin introduced, and the posts where somebody pasted raw HTML that happened to render. Spot-check the oldest posts rather than the newest — old posts were written under old rules and carry the most unusual markup.

Attachments are the second. They are large, their paths are embedded in post bodies, and the importer may copy the files without rewriting the references or rewrite the references without copying the files. Both look fine in a thread list. Open a post with an image in it.

And anything a plugin added — reputation, badges, custom fields, thread prefixes — is outside the core schema by definition and will not be carried by a core importer. Decide before the move whether those matter enough to rebuild, because rebuilding them afterwards means touching content that has already moved.

What a database dump is not

Projects frequently answer the export question with a database dump. A dump is a copy of an internal schema that one application understands, and turning it into another application's schema is the entire migration, restated as if it were solved.

It has real uses — it is a backup, and it is the input an importer reads. What it is not is a portable format, and treating it as one is how a community discovers at cutover that nobody has actually looked at what the move involves.

Before the move, and on the day

Build the address inventory first: crawl the running board, export the addresses analytics recorded, and take whatever list of externally-linked pages you can get. Union all three, then keep the correspondence the importer produces so the redirects can be generated from it rather than guessed. The full procedure is in the migration guide.

Import into a private instance, generate the redirects from the mapping, load the rules, then point the domain — with the old installation still reachable somewhere, so anything missed can be looked up rather than reconstructed. Run the inventory check against production the same day, while the source database still exists.

Questions people actually ask

How many platforms can Discourse import from?

Sixty-three import scripts ship in the repository, and fifty-nine of them fall into nine recognisable groups — classic self-hosted boards, commercial community platforms, boards attached to a CMS, hosted comment and support services, group chat, and a few others. The remaining four read one-off or bespoke formats.

Does an importer existing mean the migration is easy?

No, and the distinction matters. An importer is the difference between a documented path and an unpaid research project; it is not a guarantee about attachments, private messages, user accounts or formatting. Test it against a copy of your own data before the deadline rather than during it.

What if there is no importer for my platform?

Then the question becomes whether your software can produce a clean export at all, and that is worth testing while it still runs. Three of the ten other forum platforms catalogued here have no maintained importer into Discourse; for those the exit is an export, a conversion and someone's weekend.

Where does this list come from?

The script files in the Discourse repository, counted when this page is built rather than copied from a wiki. That is also its limit: it describes what one project ships, not every migration anyone has ever performed, and a platform's absence from it says nothing about tooling maintained elsewhere.