Migrate from Slack to Mattermost
Team chat · full migration guide
Slack → Mattermost is the smoothest of the chat migrations because Mattermost ships an official Slack import command that consumes Slack's own export bundle and reproduces channels, users, message history, and most file uploads. The import is offline (CLI-driven, not a UI button), which makes it scriptable and reproducible. The catch is that Slack's export is tier-dependent: the free plan only exports public channels, and private channels + DMs require Plus or higher with a successful Corporate Export request. Plan the migration around your Slack tier and decide ahead whether DMs are part of the cutover or whether they get retired.
Prerequisites
- Slack workspace owner (only owners can run a workspace export).
- A self-hosted Mattermost Team Edition instance — see /slack/ for the 15-minute docker-compose recipe and ~$5/mo VPS sizing.
- Shell access to the Mattermost server (the Slack importer is a `mattermost` CLI subcommand, not a UI feature).
- If you want private channels and DMs included: Slack Plus or higher and Corporate Export approved by your workspace primary owner.
- For workspaces over a few thousand messages: 2-4GB free disk on the Mattermost host for the import staging.
Step 1 — Export from Slack
-
Open the Slack export dialog
Sign into Slack web or desktop. Click your workspace name top-left → Tools & settings → Workspace settings. In the browser tab that opens click Import/Export Data → Export. Choose your date range (Everything is the default and the right choice for a migration).
-
Choose the right export tier
Free / Pro: only public channels are exported. Business+ / Enterprise: a `Corporate Export` checkbox appears that includes private channels and DMs. If your workspace is on Business+, request the Corporate Export — it requires the primary owner to confirm legal authority over employee DMs.
-
Wait for the email and download the .zip
Slack processes exports asynchronously. For a small workspace (<10k messages) the .zip is ready in minutes; large workspaces can take hours. The download link in the email expires after 7 days — pull it the same day.
-
Stage the .zip on the Mattermost host
Copy the .zip to the Mattermost server, somewhere the `mattermost` user can read it: `scp slack-export.zip mattermost-host:/tmp/`. Do not unzip — the importer wants the .zip directly.
Step 2 — Import into Mattermost
-
Create the destination team in Mattermost
In the Mattermost web UI as a system admin, create the team that will receive the imported channels (or pick an existing one). Note the team's URL slug — you'll pass it to the import command.
-
Run the Slack import command
From a shell on the Mattermost host: `docker exec -it mattermost mattermost import slack <team-slug> /mattermost/data/slack-export.zip` (path inside the container — adjust to your volume mount). The importer logs progress per channel; expect 30 seconds per 1000 messages. Channels, users, message history, threads, and most attachments transfer in this single command.
-
Verify and reconcile users
Slack exports map messages to user IDs. The importer creates Mattermost users for each Slack user with email matching; mismatches surface as 'unmatched user' warnings in the import log. Resolve by manually creating the missing user, then re-run with `--allow-merge` (Mattermost 8+) — or accept that those messages render as 'unknown user'.
-
Re-establish integrations and bots
Slack apps and bots do not migrate. Inventory them on the Slack side, then for each one either install the Mattermost equivalent (most major apps — GitHub, GitLab, Jira, PagerDuty — have first-party Mattermost integrations) or stand up an outgoing webhook with the same URL pattern.
Field / concept mapping
| Slack | Mattermost | Notes |
|---|---|---|
| Slack public channel | Mattermost public channel | Name, purpose, and full message history transfer. Pinned messages preserve. |
| Slack private channel | Mattermost private channel | Only included if you used Corporate Export. Otherwise these channels are absent from the import. |
| Slack thread | Mattermost thread | Reply chains preserve. Some emoji reactions on threaded messages may drop — re-applying is manual if it matters. |
| Slack DM / Group DM | Mattermost DM / Group Message | Only with Corporate Export. Otherwise DMs are not in the export at all. |
| Slack file upload | Mattermost file attachment | Files in the export are uploaded to Mattermost's file store. Files older than 90 days on Slack free plan may have been auto-deleted on Slack's side first. |
| Slack emoji reaction | Mattermost reaction | Standard emoji reactions transfer. Custom workspace emoji do not — re-upload them as Mattermost custom emoji and re-apply if needed. |
| Slack custom emoji | Manual re-upload | Export includes custom emoji as image files in the .zip. Upload to Mattermost via System Console → Custom Emoji. |
| Slack bot user | Manual recreation | Bots do not migrate; recreate via Mattermost integrations or outgoing webhooks. |
| Slack workflow | Manual recreation | Slack Workflow Builder content does not export. Document and rebuild as Mattermost slash commands or external automation. |
Downtime estimate
Plan a 4-hour cutover window for a 50-person team: 30 minutes to trigger the Slack export, 1-2 hours waiting for the .zip, 15-30 minutes for the actual `mattermost import` to run, and the rest for verification and DNS/announcement. The Slack workspace stays read-only for the team during the announcement window — keeping it readable but freezing new messages avoids reconciliation pain.
Common gotchas
- Slack free plan only exports public channels. If you need private channels or DMs you must be on Business+ and have a Corporate Export approval.
- Files older than 90 days are deleted on Slack free plan and will be missing from the export — they cannot be recovered.
- User matching is by email. If a user's Slack email is `alice@old-domain.com` and their Mattermost account is `alice@new-domain.com`, the import treats them as a different user. Pre-create accounts with the Slack email first and rename later.
- Slack apps that posted messages render as 'unknown app' if the app no longer exists on the Slack side at export time. Run the export while integrations are still active.
- The `mattermost import slack` command is one-shot and idempotent only by team — running it twice on the same team will create duplicate channels. Always test on a scratch team first.
Rollback plan
Slack does not delete on export — the original workspace is fully intact. If Mattermost doesn't fit, point the team back to Slack with no data loss. Keep the export .zip for 30 days as a fallback artifact that can be re-imported into Rocket.Chat or Zulip without re-running the Slack export.
Looking for setup time, monthly cost, and other alternatives? See Self-host Slack.