Migrate to Misskey from Iceshrimp
AmaseCocoa @cocoa@hackers.pub
Why migrate to Misskey
- Iceshrimp is currently being reimplemented in .NET (Iceshrimp.NET; Iceshrimp.JS is not inactive)
 - Iceshrimp.JS is not render media from media-proxy correctly (I may have reported it, but I couldn't tell whether the cause was the browser or Iceshrimp.)
 - I love Misskey
 
Compare Iceshrimp and Misskey
| Iceshrimp | Misskey (2025.10.x) | |
|---|---|---|
| Based on | Firefish (Misskey v12) | Misskey v13~ (Is not fork) | 
| Translate API | LibreTranslate, DeepL | DeepL | 
| Edit existing note | ⭕️ | ❌️ | 
| MOTD | ⭕️ | ❌️ | 
| Note length limit | variable | 3000 | 
| Search Engine | gin_trgm | LIKE, PGroonga, Meilisearch | 
| FTT (Fanout Timeline Technology) | ❌️ | ⭕️ | 
| Social Login | ⭕️ | ❌️ | 
Warning
I am not recommending this. To begin with, there are many changes between Misskey and Iceshrimp/Firefish, so there is a risk that some information may be missing.
Even so you want this migration, You must check this settings:
- SMTP (need for reset password)
- If SMTP is unavailable, either halt this migration or rewrite the backend to temporarily adapt Misskey's sign-in logic to support argon2, and further change it to automatically replace argon2 hashes with bcrypt hashes.
 
 
How to
0. shutdown your iceshrimp instance
For safety reasons, shutdown your iceshrimp instance before this migration.
systemd:
sudo systemctl stop iceshrimp
1. backup the database
If you proceed with this, you should definitely create a backup.
pg_dump -Fc (your database) > iceshrimp.dump
2. rollback database
Next, roll back the database to the Firefish equivalent.
Please continue executing the following command until the next log appears:
$ pnpm revert
# any logs
Migration IceshrimpRepo1689965609061 has been reverted successfully.
3. Run SQL
If you want migrate to Sharkey, continue with this document.
BEGIN;
-- Misskey used to have a Reversi game, Firefish dropped the tables,
-- now Misskey uses them again
CREATE TABLE "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"));
CREATE INDEX "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt");
CREATE TABLE "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"));
CREATE INDEX "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt");
CREATE INDEX "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId");
CREATE INDEX "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId");
-- this column was added by both Firefish and Misskey, but with
-- different names, let's fix it
ALTER TABLE "meta" RENAME COLUMN "ToSUrl" TO "termsOfServiceUrl";
-- fix antenna
CREATE TYPE public.new_antenna_src_enum AS ENUM ('home', 'all', 'users', 'list');
ALTER TABLE antenna ADD COLUMN new_src public.new_antenna_src_enum;
DELETE FROM antenna WHERE src NOT IN ('home', 'all', 'users', 'list');
UPDATE antenna SET new_src = src::text::new_antenna_src_enum;
ALTER TABLE antenna DROP COLUMN src;
ALTER TABLE antenna RENAME COLUMN new_src TO src;
DROP TYPE public.antenna_src_enum;
ALTER TYPE new_antenna_src_enum RENAME TO antenna_src_enum;
COMMIT;
4. Install Misskey
Next, You can install Misskey with this method.
However, do not run pnpm run init. We haven't tested it, but it may corrupt the database.
Troubleshooting
Can't login
That means you forgot to make the above settings, please give up.
Failed to load Client with APP_IMPORT 
Access /flash to initialize the client. This will delete all data, but at least it will prevent the server from becoming purely decorative.
Can't drop pg_trgm 
Access the server's database and execute DROP EXTENSION pg_trgm CASCADE; to force its removal.
Tips
How to change root account
In the current version of Misskey, the isRoot parameter has been removed. You can now use the following parameters to change the root user to another user:
BEGIN;
UPDATE meta SET "rootUserId" = '(user id)' WHERE id = 'x';
COMMIT;
and restart Misskey.
References
I would like to express my gratitude to all authors of the documents I viewed to ensure the success of this transition.