CLI tool
iptv-org/epg avatar
iptv-org/epg

iptv-org/epg: A practical EPG scraper for IPTV channel guides

Project brief: Utilities for downloading the EPG (Electronic Program Guide) for thousands of TV channels from hundreds of sources.

3,297 stars515 forksHTMLUnlicense

At a glance

What is it?
iptv-org/epg is a Node.js toolkit that downloads XMLTV guides from hundreds of sites. It is aimed at IPTV users and hobbyists who need program data for thousands of channels, but it brings real operational trade-offs.
Who is it for?
Adopt iptv-org/epg if you run your own IPTV setup and need XMLTV or JSON guides for channels that lack official EPG data, especially if you can tolerate daily or twice-daily refreshes. Avoid it if you need guaranteed uptime, low latency, or support for obscure channels not already listed in SITES.md.
Can I use it commercially?
Yes. Unlicense 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 14 days ago.
What is it written in?
Mainly HTML, 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

What problem this solves and who it targets

The project solves a narrow but persistent problem: getting program schedule data for IPTV channels that do not come with an official EPG. Many IPTV playlists list channels by name only, leaving the end user without guide data. iptv-org/epg provides a command-line tool that scrapes hundreds of websites and produces a standard XMLTV file. The README describes it as "tools for downloading the EPG for thousands of TV channels from hundreds of sources." The intended audience is clear from the usage examples: people who already have an IPTV player, know how to run a terminal command, and need a guide.xml file to feed into that player. It is not a turnkey service. You still need to pick a site, run the grab, and serve the result.

How the scraping mechanism works

The core operation is a single command: npm run grab, which accepts a list of site names. Each site corresponds to a parser in the /sites directory, and the parser knows how to extract channel identifiers and program listings from that particular source. The README shows that you can pass a comma-separated list, for example --sites=example1.com,example2.com, and the tool will merge the results into one guide.xml. The output format is XMLTV by default, but the Docker environment variables suggest JSON output is also possible (JSON=true). The tool fetches each channel's guide sequentially by default, with a per-request timeout of 30000 milliseconds and a delay between requests. You can raise the concurrency with --maxConnections, but the README warns that heavy load may cause sites to return errors or block your access. That is a concrete operational constraint: the scraper is only as reliable as the sites it scrapes, and those sites have no obligation to tolerate your requests.

Installation and the exact commands you need

Installation follows the standard Node.js path. You need Node.js and Git. The README instructs you to clone with git clone --depth 1 -b master https://github.com/iptv-org/epg.git, then cd epg and run npm install. After that, you can start a download with npm run grab --- --sites=example.com. The triple dash is notable: it separates npm's own arguments from the script's arguments. If you want to restrict to specific languages, use --lang en,id. For a custom channel list, you create an XML file with <channel> elements that include site, lang, xmltv_id, and site_id attributes, then pass it with --channels path/to/custom.channels.xml. The output file defaults to guide.xml, but you can change it with --output. The README also shows a pattern for splitting output by site: --output=guides/{site}.xml. These commands are concrete and reproducible, which is a strength of the documentation.

Docker deployment and environment variables

For users who prefer containers, the project publishes a Docker image at ghcr.io/iptv-org/epg:master. The basic run command mounts a channels.xml file into the container and exposes port 3000. By default, the container downloads the guide every day at 00:00 UTC and saves it to /epg/public/guide.xml. You can change the schedule with the CRON_SCHEDULE environment variable, for example "0 0,12 * * *" for twice daily. Other variables control concurrency (MAX_CONNECTIONS), output formats (GZIP, JSON), request behavior (TIMEOUT, DELAY, PROXY), and how many days of data to fetch (DAYS). There is also RUN_AT_STARTUP to trigger an immediate download when the container starts. This makes the tool easy to integrate into a home server setup. The main caveat is that the container image is tied to the master branch, so you are always running the latest commit, which may change behavior without notice.

A real limitation: breakage and site dependence

The biggest limitation is that the tool depends entirely on third-party websites that can change their HTML structure at any time. The README does not claim any fallback or error recovery beyond timeouts and delays. If a site blocks your IP or changes its markup, the grab will fail or produce incomplete data. The documentation itself warns that "under heavy load some sites may start return an error or completely block your access." That is a genuine failure mode. Another limitation is the channel coverage: you are restricted to the sites listed in SITES.md and the channels defined in each site's parser. If your favorite channel is not there, you cannot scrape it without writing your own parser. The README shows a contribution section, but it does not promise that every channel in the world is covered. For a user with niche channels, this tool may be the wrong choice.

Alternative approaches and how they differ

The obvious alternative is to use a hosted EPG service that already aggregates data, such as the one provided by iptv-org itself at https://iptv-org.github.io/. That service is the output of this same project, but the difference is that you do not run anything yourself. You just point your player at a URL. The trade-off is control and customization. With the hosted version, you cannot choose your own sites, set a custom schedule, or apply a proxy. With iptv-org/epg, you get those options, but you also get the maintenance burden. Another alternative is to build your own scraper for a single site using a generic HTTP client and an XML generator. That gives you full control but requires you to handle site changes yourself. The project's approach is to centralize the parsing logic for hundreds of sites, which is a real advantage if you need many channels, but it also means you inherit every site's quirks.

Maintenance, upgrade cost, and license

The project is actively maintained in the sense that the repository is not archived and has a GitHub Actions workflow for updates. The README lists an update procedure: git pull and npm install. That is simple, but it implies that you should track the master branch, which may introduce breaking changes in the CLI or the site parsers. There are no recent releases listed, so you cannot pin to a stable version. The license is Unlicense, which is a public domain dedication. That means you can use, modify, and redistribute the code without restriction. The practical implication is that there is no warranty and no liability protection, so you are responsible for how you use the scraped data. The README does not mention any rate-limiting compliance or terms-of-service considerations, so you should check the legality of scraping each source site yourself.

Editorial conclusion

Adopt iptv-org/epg if you run your own IPTV setup and need XMLTV or JSON guides for channels that lack official EPG data, especially if you can tolerate daily or twice-daily refreshes. Avoid it if you need guaranteed uptime, low latency, or support for obscure channels not already listed in SITES.md. Before adopting, verify that your target channels exist in the sites directory, test the grab command with a single site and a small channel list, and check the Unlicense terms if your project has licensing constraints.

Official sources

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

Community notes