twix2bsky

twix2bsky is a simple tool to migrate tweets from Twitter/X to Bluesky.
twix2bsky works from a Twitter/X archive (the zip file or its unzipped content).
cmd/twix2bsky-import
Command twix2bsky-import imports a Twitter/X archive into a twix (SQLite) database, rebuilding the messages/threads graph.
$> twix2bsky-import -h
twix2bsky-import imports a Twitter/X archive.
Usage: twix2bsky-import [OPTIONS] TWITTER-ARCHIVE [TWITTER-ARCHIVE-1 [TWITTER-ARCHIVE-2 [...]]]
Example:
$> twix2bsky-import ./twitter-xxx.zip
$> twix2bsky-import ./twitter-archive-dir
Options:
-o string
path to output SQLite db (default "twix.db")
cmd/twix2bsky-assoc-users
Command twix2bsky-assoc-users tries to associate Twitter/X user handles with their Bluesky counterpart.
It's useful for converting tweets into Bluesky posts.
$> twix2bsky-assoc-users -h
twix2bsky-assoc-users tries to associate Twitter/X users with Bluesky profiles.
Usage: twix2bsky-assoc-users [OPTIONS] TWITTER-ARCHIVE [TWITTER-ARCHIVE-1 [TWITTER-ARCHIVE-2 [...]]]
Example:
$> twix2bsky-assoc-users ./twitter-xxx.zip
$> twix2bsky-assoc-users ./twitter-archive-dir ./twitter-xxx.zip
Options:
-bsky-auth string
path to Bluesky credentials
-db string
path to twix SQLite db (default "twix.db")
To achieve this, the Bluesky API is used, so one needs credentials.
These credentials are expected to be stored in a file with the following structure:
twix2bsky {
my-user-handle {
user my-user-handle.bsky.social
host https://bsky.social
pass xxxx-xxxx-xxxx-xxxx
}
}
The default location for this credentials file is ~/.config/twix2bsky.cfg.
We advise to use a password app for the Bluesky credentials (instead of your Bluesky account password).
cmd/twix2bsky-cnv
Command twix2bsky-cnv tries to convert Twitter/X messages into Bluesky posts.
$> twix2bsky-cnv -h
twix2bsky-cnv converts a (subset of a) Twitter/X archive into Bluesky skeets.
Usage: twix2bsky-cnv [OPTIONS] TWITTER-ARCHIVE [TWITTER-ARCHIVE-1 [TWITTER-ARCHIVE-2 [...]]]
Example:
$> twix2bsky-cnv ./twitter-xxx.zip
$> twix2bsky-cnv ./twitter-archive-dir ./twitter-xxx.zip
Options:
-bsky-auth string
path to Bluesky credentials
-db string
path to twix SQLite db (default "twix.db")
twix2bsky-cnv will try to best handle the impedance mismatch between Twitter/X constraints and Bluesky ones:
- Bluesky doesn't allow posts that mix videos and images: such a tweet will be split into one post (with an image or video) and replies with the remaining medias
- Bluesky doesn't allow multiple videos or videos longer than 60 seconds: such a tweet will be split into one post with the first 60 seconds of the first video and replies with the remaining 60s-chunks (
ffmpeg will need to be available for this)
- Bluesky doesn't allow posts with images bigger than ~976.56kB: such images will be iteratively downsized in resolution until the size constrain is fulfilled
- Bluesky doesn't allow posts with more than 300 graphemes: such tweets are cut in half, trying to find the last
\n in the [0, 150) text range (or a space if no line return could be found), the second half of the tweet is made a reply to the post corresponding to the first half
twix2bsky-cnv also tries to replace @user mentions in the Twitter/X message with the Bluesky handle (using the association data from twix2bsky-assoc-users) unless this pushes the post over its text budget (300 graphemes).
Otherwise, and if no Bluesky handle could be found, the @user mention is replaced with #user.