TediCross relays messages between Telegram and Discord, if you run it yourself
A bot that bridges chats between Telegram and Discord.
At a glance
- What is it?
- TediCross is a self-hosted bot that bridges Telegram chats and Discord channels, relaying text, media, replies, edits and supported deletions. It requires your own bot tokens and a host, and the 1.0.0 line is still labelled a pre-release work in progress.
- Who is it for?
- Adopt TediCross if you need a private bridge between a Telegram group and a Discord channel and you are willing to run Node.js 22.13 or newer on your own host, supply both bot tokens, and accept that the 1.0.0 line is still a pre-release. Do not deploy it as the only path between two communities while it is in that state, and do not expect it to carry voice chat or a full feature parity with either platform.
- 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 received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A bridge you host, with tokens you supply
TediCross is a bot that bridges chats between Telegram and Discord, and the first thing to understand is that there is no public instance. The documentation states plainly that there is no public TediCross bot, that you need your own Telegram bot, your own Discord application, and a host running Node.js 22.13 or newer. That constraint is the product. Anyone can run a hosted bridge, but a hosted bridge also sees every message that passes through it, and a community that wants its internal conversation replicated across two platforms generally does not want a stranger reading it. The audience is therefore administrators of small communities, often people who already run a Discord server and want the same discussion reachable from Telegram, or the other way round. The project is a TypeScript application using discord.js on the Discord side and telegraf on the Telegram side, and the repository topics list both libraries alongside terms like discord-telegram and telegram-discord, which says the same thing.
What actually crosses the bridge, and what does not
The relay covers text, media, replies, edits, and supported deletion events. The word supported in that list does a lot of work, and the documentation is careful to qualify it rather than claim full parity. Edits matter more than they first appear, because a bridged conversation where an edited message stays visible in its original form on the other platform is confusing. Replies matter because the reply context has to be reconstructed on the far side, and the dependency list includes simple-markdown, mime and ogg-opus-decoder, which is consistent with handling media attachments, their content types and voice messages by decoding them before forwarding. The mime package is what tells the bridge how to label a file, and opus decoding is what lets an audio clip be re-encoded into something the far platform accepts. The honest framing is that TediCross handles a defined set of message events well and leaves the rest alone, and anyone deploying it for a community should check the event list against the message types their members actually use.
Configuration is a YAML file of tokens and bridge IDs
Setup is three steps. You follow the installation guide, you create settings.yaml from example.settings.yaml and configure your tokens and bridge IDs using the configuration guide, and you start the bot with npm start. The example file sits at the repository root and the real settings file is expected beside it, which is also why the data directory matters: the development script starts the app with an -i data/ flag so that the local data folder is ignored while watching, and the container is started with a --config and --data-dir pair pointing at a mounted settings file and a data volume. The compose file states the whole procedure in its own header comment, and the command it gives is:
# docker compose up --build -dThe package manifest shows the script surface behind that, where build runs the TypeScript compiler and start runs the compiled entry point:
"scripts": {
"build": "tsc",
"start": "node dist/main.js",The state is kept in SQLite, with sqlite and sqlite3 both in the dependency list, so bridges, topics and any mapping between the two platforms persist across restarts in an ordinary database file inside the data directory. Bridge and topic setup has its own guide under docs/guides, and a troubleshooting guide sits beside it. Configuration is a source of real complexity in any bridge, since one side addresses chats and channels and the other addresses topics and threads, and the guide exists because that mapping needs to be spelled out.
The 1.0.0 pre-release changed the ground under existing installs
Two warnings sit at the top of the project documentation and both matter. The first says TediCross 1.0.0 includes breaking changes, that the Node.js minimum, the dependencies and some configuration have changed since the 0.x series, and that you should review the configuration guide and back up your settings and data before upgrading. The second says the current 1.0.0 pre-release is still a work in progress and has not had broad testing, that you should try it in a separate instance and report rough edges in GitHub Issues, and that you should avoid upgrading your only production instance until the stable release. Those two warnings are in tension, and the practical reading is that an upgrade path exists for people with a spare instance and no safe path for a single instance serving a live community. The version history explains why the change is this large. The tagged releases stop at v0.12.4 in July 2024, with v0.12.3 in September 2023 and v0.12.2 in August 2023, so the 0.x line had been quiet for a long while before the 1.0.0 rewrite. The last push to the repository was on 2026-10-17, so the work is current even though the release tags are not.
Running it in a container with a hardened filesystem
The repository ships a Dockerfile and a compose.yaml, and the container definition is stricter than most. The image is built on node:24-alpine with a build stage that installs python3, g++ and make, which the sqlite3 native module needs, and the runtime stage copies only the package manifest, the pruned node_modules and the compiled dist directory, then runs as the node user with the data directory created and owned by that user. The compose service builds from the local Dockerfile, runs with init: true and restart: unless-stopped, and passes the config and data directory as command arguments. The token handling is explicit: the environment block defines TELEGRAM_BOT_TOKEN and DISCORD_BOT_TOKEN, with a comment saying these should be set in your shell or a local .env file when the settings use token: env, and that tokens written directly in settings.yaml do not need those entries. The rest of the hardening is worth copying into your own deployments regardless of this project: the settings file is bind mounted read only with create_host_path: false, the container root filesystem is read only, /tmp is a tmpfs with noexec, nosuid and nodev and a 16 megabyte size limit, all capabilities are dropped, no-new-privileges is set, and the process limit is 64.
Where a bridge stops being the right answer
There are cases where relaying messages is the wrong shape of solution. If your community needs voice chat, or threads with their own permission model, or file sharing with workspace level access control, a message relay will not reproduce those, and the two platforms are not equivalent in the first place. A bridge also creates an obligation rather than removing one, because a moderator now has two places to look, and deletion events are only relayed when supported, which means a message removed on one side may persist on the other. The alternative approach is to pick one platform as the home and point people at it, with a channel announcement on the other side rather than a full mirror, or to use a shared space that both audiences already live in. That is less convenient for the members and much less work for the administrator. A second alternative is a generic webhook relay between the two platforms, which you configure yourself in a handful of lines of code; that gives you full control over what is forwarded and what is filtered, at the cost of maintaining the event handling, the media re-encoding and the state that TediCross already handles for you.
Editorial conclusion
Adopt TediCross if you need a private bridge between a Telegram group and a Discord channel and you are willing to run Node.js 22.13 or newer on your own host, supply both bot tokens, and accept that the 1.0.0 line is still a pre-release. Do not deploy it as the only path between two communities while it is in that state, and do not expect it to carry voice chat or a full feature parity with either platform. Before you upgrade an existing instance, back up your settings and data, read the configuration guide for the breaking changes in 1.0.0, and confirm the bridge and topic identifiers in your settings.yaml before you start the bot.
Frequently asked questions
What is TediCross and how do I run it?
TediCross is a self-hosted bot that bridges Telegram chats and Discord channels, relaying text, media, replies, edits and supported deletion events. You need your own Telegram bot, your own Discord application and a host running Node.js 22.13 or newer, and you start it with npm start after creating settings.yaml from example.settings.yaml.
Is there a public TediCross bot I can use without hosting?
No. The documentation states there is no public TediCross bot, so running one yourself is the only option. That is also why a self-hosted setup matters for privacy, since every relayed message passes through the machine you control.
Can I deploy TediCross with Docker?
Yes, the repository includes a Dockerfile and a compose.yaml with a hardened service definition that mounts settings.yaml read only, keeps a persistent volume for the data directory and passes the config and data directory as command arguments. The compose file expects TELEGRAM_BOT_TOKEN and DISCORD_BOT_TOKEN in the environment when the settings use token: env.
Is TediCross 1.0.0 safe to upgrade to?
The documentation warns that 1.0.0 includes breaking changes to the Node.js minimum, the dependencies and some configuration, and that the pre-release has not had broad testing. It recommends trying it in a separate instance and avoiding upgrading your only production instance until the stable release, and back up your settings and data first.
What licence is TediCross released under?
TediCross is licensed under the MIT License, with the licence file kept at the root of the repository and the MIT identifier also recorded in the package manifest and in the container image labels.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tedicross-tedicross)Was this useful?