Self-hosted service
FxEmbed/FxEmbed avatar
FxEmbed/FxEmbed

FxEmbed: A Self-Hostable Fix for Broken X and Bluesky Embeds

Fix X/Twitter and Bluesky embeds! Use multiple images, videos, polls, translations and more on Discord, Telegram and others.

5,039 stars223 forksTypeScriptMIT

At a glance

What is it?
FxEmbed is a Cloudflare Worker that rewrites X, Twitter, and Bluesky links into rich embeds for Discord, Telegram, and other platforms. It is MIT-licensed, self-hostable via Docker, and worth a look if you are tired of single-image previews.
Who is it for?
Adopt FxEmbed if you run a Discord or Telegram community that regularly shares X, Twitter, or Bluesky links and you want richer embeds without relying on a third-party public service. Skip it if you cannot handle the operational burden of running a Cloudflare Worker or if your traffic is trivial and the public fxtwitter.com instance is reliable enough.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem: Link Previews That Lose Most of the Post

When you paste a link to an X post or a Bluesky post into Discord or Telegram, the platform fetches a preview. For X, that preview is often a single image and a short text snippet. Videos, polls, multiple images, and quoted posts are missing. FxEmbed exists to fix that. It is a service that re-renders the link as a richer embed, showing videos, polls, translations, and multiple images. The intended users are community moderators, bot operators, and anyone who runs a chat server where people share social media links frequently. The README positions it as the home of FxTwitter, FixupX, and FxBluesky, which are the three URL rewriting schemes it supports.

How It Works: Host-Header Routing and URL Prefixes

FxEmbed is a Cloudflare Worker, not a conventional web server. It routes requests based on the Host header, which is how it distinguishes between the fxtwitter.com, fixupx.com, and fxbluesky.com realms. The user-facing mechanism is simple: you add a prefix to the original link. For twitter.com, you insert 'fx' before the domain, so twitter.com/user/status/123 becomes fxtwitter.com/user/status/123. For x.com, you insert 'fixup', so x.com/user/status/123 becomes fixupx.com/user/status/123. For bsky.app, you add 'fx', so bsky.app/profile/user/post/abc becomes fxbsky.app/profile/user/post/abc. The worker then fetches the original post and generates an embed that Discord or Telegram can render. The README shows a curl command with a Host header and a Discordbot User-Agent, which tells you that the worker checks the User-Agent to decide what kind of embed to serve.

Running It: Docker and the Local Workers Runtime

The README gives a clear path to a local deployment. You copy three configuration files: .env.example to .env, wrangler.example.toml to wrangler.toml, and branding.example.json to branding.json. The .env file holds environment variables, wrangler.toml holds worker configuration, and branding.json is for custom branding. Then you run 'docker compose up -d --build'. The Docker image is based on node:24-bookworm-slim because the Wrangler workerd binary is glibc-linked and does not run reliably on Alpine. That is a concrete detail: if you are used to Alpine-based images for size, you cannot use them here. The worker listens on localhost:8787. Because routing is by Host header, you test a specific realm with a curl command that sets the Host to fxtwitter.com and the User-Agent to Discordbot/2.0. Environment variables are bundled at build time, so changing domain lists requires a rebuild. Runtime secrets like CREDENTIAL_KEY and EXCEPTION_DISCORD_WEBHOOK can be passed through the shell or a Compose .env file.

Configuration Keys and Customization

The three configuration files are the core of customization. The .env file contains environment variables, and the README names two specific runtime secrets: CREDENTIAL_KEY and EXCEPTION_DISCORD_WEBHOOK. The CREDENTIAL_KEY is likely used to authenticate admin or API calls, though the README does not explain its exact role. EXCEPTION_DISCORD_WEBHOOK appears to be a webhook URL for sending error notifications to Discord. The branding.example.json file suggests you can customize the appearance of the embed, perhaps the footer or the icon, but the README gives no details on its schema. The wrangler.example.toml is the standard Cloudflare Wrangler configuration, which you would edit to set your own domains or zones. The documentation site, docs.fxembed.com, has an API reference and a deployment guide, but the README does not list the API endpoints. If you need to change the domain list, you must edit wrangler.toml and rebuild the Docker image, because those values are baked in at build time.

Limitations and Failure Modes

The most obvious limitation is that FxEmbed depends on the Host header to decide which realm to serve. If you run it locally and access it via localhost, you only see the default realm. That is why the README shows the curl command with a Host header. In production, you need to have DNS pointing the fxtwitter.com, fixupx.com, and fxbsky.com domains (or your own domains) to your worker. Another limitation is that the worker fetches the original post, so if X or Bluesky changes their API or blocks the worker's requests, embeds will break. The README does not mention any fallback behavior. Also, the Docker image runs Wrangler's local runtime, which is not the same as the Cloudflare edge environment. That means performance and behavior may differ between local and production deployments. The README does not state whether the worker handles rate limits from Discord or Telegram, so you may need to add your own caching or throttling if you expect high traffic.

Alternatives: Public Instances and Other Embed Services

The most direct alternative is to use the public fxtwitter.com instance that the FxEmbed project runs. The README links to a status page at status.fxtwitter.com, so you can check uptime. Using the public instance requires no setup, but you are at the mercy of the project's availability and any rate limits it imposes. Another alternative is to use Discord's native embed system, which works for some links but does not handle multiple images or videos well. There are also commercial services like Microlink or Embed.ly that provide generic link previews, but they are not specific to X or Bluesky and may not support polls or translations. The key difference is that FxEmbed is self-hostable and open source, so you control the deployment and can customize the branding. The trade-off is that you have to maintain a worker and keep up with changes to X and Bluesky's platforms.

Maintenance, License, and Upgrade Path

FxEmbed is licensed under the MIT license, which is permissive and allows commercial use, modification, and redistribution, with the requirement to preserve the copyright notice. The README explicitly says 'Licensed under the permissive MIT license. Feel free to send a pull request!', so the project welcomes contributions. There are no recent releases listed, but the repository has an active build and tests workflow, as shown by the badges. That means you are likely to get updates via the main branch rather than tagged releases. The upgrade path is to pull the latest code and rebuild the Docker image. Because environment variables are bundled at build time, you must rebuild after any configuration change. The README does not mention a migration guide or a changelog, so you should check the commit history before upgrading. The project also credits a multi-image combiner called Mosaic, which is a separate component, so if you fork or modify, you need to keep that dependency in mind.

Editorial conclusion

Adopt FxEmbed if you run a Discord or Telegram community that regularly shares X, Twitter, or Bluesky links and you want richer embeds without relying on a third-party public service. Skip it if you cannot handle the operational burden of running a Cloudflare Worker or if your traffic is trivial and the public fxtwitter.com instance is reliable enough. Before committing, verify that your expected link patterns (including quotes, polls, and translations) work with the current build, and check the documentation for any rate limits or host-header routing quirks. The project is MIT-licensed and actively maintained, but it is a worker, not a traditional server, so plan your deployment accordingly.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
Community notes

Community notes