Open-source project
miantiao-me/BroadcastChannel avatar
miantiao-me/BroadcastChannel

BroadcastChannel: publish a Telegram channel as a 0-JS microblog with Astro

Turn your Telegram Channel into a MicroBlog.

2,092 stars1,043 forksCSSAGPL-3.0

At a glance

What is it?
BroadcastChannel pulls posts from a public Telegram channel and renders them as a static-style microblog with 0 JavaScript on the browser side. It deploys to Docker or serverless platforms and needs only the channel username to get started.
Who is it for?
BroadcastChannel suits anyone who already runs a public Telegram channel and wants a web-readable archive without setting up a separate CMS. Skip it when your channel is private, when you need a commenting system that aggregates outside Telegram, or when self-hosting means you cannot publish modified source under AGPL-3.0.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly CSS, according to GitHub's language statistics.

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

Editorial analysis

BroadcastChannel reads a public Telegram channel and renders posts as a 0-JS microblog

BroadcastChannel addresses a specific publishing gap: a Telegram channel is a good place to write short posts, but it is not a web page, does not produce RSS, and has no SEO value on its own. BroadcastChannel bridges that gap by reading a public channel and rendering its posts as a website with 0 JavaScript on the browser side.

The CMS is Telegram Channels, per the README's Tech Stack section. There is no content database to manage, no admin panel and no separate writing interface. Posts go into Telegram as usual, and BroadcastChannel reads them on demand via the Telegram public channel preview at t.me/s/.

The result includes a /sitemap.xml, RSS at /rss.xml and RSS JSON at /rss.json, and a blog home showing posts from the channel. The channel must be public: private channels are not accessible through the Telegram preview endpoint that BroadcastChannel reads.

Astro v7, [email protected], and sanitize-html 2.17.5 make up the core stack

The framework is Astro, pinned to ^7.0.9 in package.json. Server-side rendering is the default mode, which is what makes the 0-JS claim accurate: Astro builds the pages on the server and sends finished HTML to the browser. No client-side Astro runtime loads on page view.

The package manager is pnpm, fixed at version 11.13.0 in the packageManager field of package.json. pnpm-workspace.yaml and pnpm-lock.yaml both appear at the root, so npm and yarn are not tested install paths. Three key dependencies handle content: cheerio at 1.0.0-rc.12 parses the Telegram channel HTML, sanitize-html at 2.17.5 cleans it, and ofetch at ^1.5.1 fetches the channel data. Both cheerio and sanitize-html are pinned to exact or near-exact versions, which is significant for a project that handles external HTML.

The project is licensed under AGPL-3.0. Styling comes from Tailwind CSS at ^4.3.2, and prismjs at ^1.30.0 handles code syntax highlighting in posts.

Docker exposes port 4321 and the minimal serverless config needs only CHANNEL

Two deployment paths exist: Docker and serverless. For Docker, the README gives a two-step command sequence. The second step starts the container:

bash
docker run -d --name broadcastchannel -p 4321:4321 -e CHANNEL=miantiao_me ghcr.io/miantiao-me/broadcastchannel:main

Replace miantiao_me with your own channel's username (the string after t.me/). The container runs on port 4321 and the CHANNEL variable is the only required configuration for a working deployment.

For serverless, the minimal config is one environment variable:

env
CHANNEL=miantiao_me

The README lists 7 steps for serverless: fork the repository, create a project on a supported platform, select BroadcastChannel and the Astro framework, set the CHANNEL variable, save and deploy, optionally bind a domain, and update the fork via GitHub's web UI. Supported platforms are Cloudflare Workers, Netlify, Vercel and EdgeOne. EdgeOne is detected automatically through std-env's edgeone_pages provider or the EDGEONE_PROJECT_ID/EO_MAKERS environment variables.

Cloudflare Pages SSR is not supported and the README states that twice

One deployment constraint appears in two different places in the README. First in the platform overview: 'Cloudflare Pages SSR is not supported with Astro 6 + @astrojs/cloudflare v13; use Workers for Cloudflare deployments.' Then again in the Cloudflare Workers section: 'Cloudflare Pages SSR is not supported with Astro 6 + @astrojs/cloudflare v13. Migrate Pages deployments to Workers.'

The second mention adds a concrete migration instruction that the first does not. Users who had an existing Pages deployment before this restriction was introduced get an explicit action: move to Workers.

For Workers, the deployment commands are:

bash
pnpm exec wrangler login
SERVER_ADAPTER=cloudflare_workers pnpm build
pnpm exec wrangler deploy

Runtime configuration such as CHANNEL goes in the Workers dashboard or via pnpm exec wrangler secret put CHANNEL. The SERVER_ADAPTER variable defaults to automatic detection and only needs to be set explicitly when that detection does not produce the right adapter.

Ten themes load via HEADER_INJECT, but exactly one override is allowed at a time

The README defines a clear loading rule: the Base theme is always loaded. To use a different look, set HEADER_INJECT to one stylesheet link. The .env.example comment says 'never combine themes.' The word 'exactly' appears in the README's description of the loading rule: 'load exactly one built-in override.'

The 10 built-in themes are Sepia, Aria, Terminal Amber, Terminal Green, Terminal Cyan, Terminal Magenta, HN News, TG Channel, ZAE and Polar. Activating Polar looks like this:

env
HEADER_INJECT='<link rel="stylesheet" href="/themes/polar.css">'

HN News, TG Channel, ZAE and Polar are fixed-light themes, meaning they have no dark mode variant. The README mentions this group specifically before the truncation point. THEMES.md at the repository root covers all built-in paths, platform values, custom CSS options and security notes for the injection mechanism.

BroadcastChannel only reads public channels, and Bear Blog takes a different CMS approach

The most direct limitation of BroadcastChannel is that it reads the Telegram public channel preview endpoint. Private channels do not have a public preview, so the tool cannot bridge them to the web. The CHANNEL variable holds only a public channel username, and the project provides no authentication mechanism for private channels.

For someone who wants a minimal blog without the Telegram dependency, Bear Blog is the closest comparison. The README cites Bear Blog as CSS inspiration for the base theme (independently implemented, with no official affiliation or Bear source files). Bear Blog is a standalone blogging platform that stores its own content. BroadcastChannel has no content storage of its own: all posts live in Telegram, and the site is a reader over that data.

The practical difference is that BroadcastChannel's content strategy is tied to Telegram's uptime and API behaviour. If the public channel preview endpoint changes, the site breaks.

The full configuration covers proxies, social links and a trusted-admin HTML injection point

Beyond the minimal CHANNEL variable, the full configuration reference covers LOCALE and TIMEZONE for display formatting, social handles for TELEGRAM, TWITTER, GITHUB, MASTODON and BLUESKY, and full URLs for DISCORD and PODCAST. TAGS, LINKS and NAVS accept comma-separated or semicolon-separated lists to add tag filtering, footer links and navigation items.

Two variables warrant care. HEADER_INJECT is described in .env.example as 'trusted-admin raw HTML injection,' meaning it accepts arbitrary HTML that renders in every page header. The comment in .env.example includes a security note that sends readers to THEMES.md. STATIC_PROXY and TARGET_WHITELIST let the deployment proxy requests through a custom host: TARGET_WHITELIST accepts hostname-only values separated by commas, with no protocol, port or path allowed.

SEO controls are NOFOLLOW and NOINDEX, both false by default. The last push to the repository was on 2026-09-26.

Editorial conclusion

BroadcastChannel suits anyone who already runs a public Telegram channel and wants a web-readable archive without setting up a separate CMS. Skip it when your channel is private, when you need a commenting system that aggregates outside Telegram, or when self-hosting means you cannot publish modified source under AGPL-3.0. Before deploying to Cloudflare, verify you are targeting Workers rather than Pages, since Pages SSR is not supported with the current Astro and @astrojs/cloudflare adapter combination, and read THEMES.md before setting HEADER_INJECT.

Frequently asked questions

How do I deploy BroadcastChannel?

Two paths exist: Docker using the ghcr.io/miantiao-me/broadcastchannel:main image on port 4321, or serverless on Cloudflare Workers, Netlify, Vercel or EdgeOne. The only required configuration is the CHANNEL environment variable set to your Telegram channel username.

Does BroadcastChannel work with private Telegram channels?

No. BroadcastChannel reads the public Telegram channel preview endpoint, which is only available for public channels. Private channels have no public preview and cannot be bridged with this tool.

Does BroadcastChannel work on Cloudflare Pages?

No. The README states that Cloudflare Pages SSR is not supported with Astro 6 and @astrojs/cloudflare v13, and instructs users to migrate Pages deployments to Cloudflare Workers instead.

How do I change the theme in BroadcastChannel?

Set HEADER_INJECT to a stylesheet link pointing to one of the built-in theme paths under /themes/. The Base theme loads by default. Load exactly one override at a time; combining themes is not supported.

What RSS feeds does BroadcastChannel generate?

BroadcastChannel generates two feeds: /rss.xml and /rss.json. Both are listed in the README's feature list alongside the /sitemap.xml endpoint.

Official sources

  1. License: AGPL-3.0
  2. miantiao-me/BroadcastChannel on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/miantiao-me-broadcastchannel.svg)](https://hysenlabs.com/projects/miantiao-me-broadcastchannel)