{"id":13342,"library":"iptv-playlist-parser","title":"IPTV Playlist Parser","description":"iptv-playlist-parser is a utility designed to parse M3U and M3U8 IPTV playlists into a structured JavaScript object format. It is currently at version 0.15.2 and actively maintained, with frequent small releases addressing bug fixes and minor improvements rather than a strict release cadence. The library aims to provide a straightforward way to extract program information, group titles, TVG attributes (ID, name, URL, logo, shift), and HTTP options (referrer, user-agent) from raw playlist data. Its primary differentiator is its focused utility for IPTV playlist formats, providing a normalized output structure for consumption in applications that need to process and display IPTV channel listings. It is a lightweight solution without external runtime dependencies, relying on standard Node.js modules for file and URL operations.","status":"active","version":"0.15.2","language":"javascript","source_language":"en","source_url":"git://github.com/freearhey/iptv-playlist-parser","tags":["javascript","iptv","playlist","parser","m3u","m3u8","typescript"],"install":[{"cmd":"npm install iptv-playlist-parser","lang":"bash","label":"npm"},{"cmd":"yarn add iptv-playlist-parser","lang":"bash","label":"yarn"},{"cmd":"pnpm add iptv-playlist-parser","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily exports a `parse` function as a named export, not a default export, despite some README examples suggesting otherwise.","wrong":"import parser from 'iptv-playlist-parser'","symbol":"parse","correct":"import { parse } from 'iptv-playlist-parser'"},{"note":"For CommonJS, destructure the `parse` function directly. The module object itself is not the parser function.","wrong":"const parser = require('iptv-playlist-parser')","symbol":"parse","correct":"const { parse } = require('iptv-playlist-parser')"}],"quickstart":{"code":"import { parse } from 'iptv-playlist-parser'\n\nconst playlistString = `#EXTM3U x-tvg-url=\"http://example.com/epg.xml.gz\"\n#EXTINF:-1 tvg-id=\"cnn.us\" tvg-name=\"CNN\" tvg-url=\"http://195.154.221.171/epg/guide.xml.gz\" tvg-shift=\"-4.5\" timeshift=\"3\" catchup=\"shift\" catchup-days=\"3\" catchup-source=\"https://m3u-server/hls-apple-s4-c494-abcdef.m3u8?utc=325234234&lutc=3123125324\" lang=\"eng\" tvg-logo=\"http://example.com/logo.png\" group-title=\"News\",CNN (US)\n#EXTGRP:News\n#EXTVLCOPT:http-referrer=http://example.com/\n#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Macintosh; Intel OS X 10_14_5)\nhttp://example.com/stream.m3u8`\n\nconst parsedResult = parse(playlistString)\n\nconsole.log(JSON.stringify(parsedResult, null, 2))\n/* Expected Output:\n{\n  \"header\": {\n    \"attrs\": {\n      \"x-tvg-url\": \"http://example.com/epg.xml.gz\"\n    },\n    \"raw\": \"#EXTM3U x-tvg-url=\\\"http://example.com/epg.xml.gz\\\"\"\n  },\n  \"items\": [\n    {\n      \"name\": \"CNN (US)\",\n      \"tvg\": {\n        \"id\": \"cnn.us\",\n        \"name\": \"CNN\",\n        \"url\": \"http://195.154.221.171/epg/guide.xml.gz\",\n        \"logo\": \"http://example.com/logo.png\",\n        \"rec\": \"\",\n        \"shift\": \"-4.5\"\n      },\n      \"group\": {\n        \"title\": \"News\"\n      },\n      \"http\": {\n        \"referrer\": \"http://example.com/\",\n        \"user-agent\": \"Mozilla/5.0 (Macintosh; Intel OS X 10_14_5)\"\n      },\n      \"url\": \"http://example.com/stream.m3u8\",\n      \"raw\": \"#EXTINF:-1 tvg-id=\\\"cnn.us\\\" tvg-name=\\\"CNN\\\" tvg-url=\\\"http://195.154.221.171/epg/guide.xml.gz\\\" tvg-shift=\\\"-4.5\\\" timeshift=\\\"3\\\" catchup=\\\"shift\\\" catchup-days=\\\"3\\\" catchup-source=\\\"https://m3u-server/hls-apple-s4-c494-abcdef.m3u8?utc=325234234&lutc=3123125324\\\" tvg-logo=\\\"http://example.com/logo.png\\\" group-title=\\\"News\\\",CNN (US)\\n#EXTGRP:News\\n#EXTVLCOPT:http-referrer=http://example.com/\\n#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Macintosh; Intel OS X 10_14_5)\\nhttp://example.com/stream.m3u8\",\n      \"line\": 2,\n      \"timeshift\": \"3\",\n      \"catchup\": {\n        \"type\": \"shift\",\n        \"source\": \"https://m3u-server/hls-apple-s4-c494-abcdef.m3u8?utc=325234234&lutc=3123125324\",\n        \"days\": \"3\"\n      },\n      \"lang\": \"eng\"\n    }\n  ]\n}\n*/","lang":"typescript","description":"Demonstrates parsing a raw M3U playlist string and logging the structured JavaScript object output, including header and item details."},"warnings":[{"fix":"Migrate any logic relying on `tvg-language` or `tvg-country` attributes to use alternative properties or external data sources.","message":"Support for `tvg-language` and `tvg-country` attributes was completely removed, meaning these attributes will no longer be parsed or included in the output object.","severity":"breaking","affected_versions":">=0.12.0"},{"fix":"If your application relied on the `url` property being stripped of embedded headers in older versions, adjust your parsing logic or update to v0.15.0+ and process the `url` property as needed.","message":"Prior to v0.15.0, links containing headers embedded in the URL (e.g., `url|Header=Value`) might not have been stored in their original, unparsed form in the `url` property. The behavior changed to preserve the original URL string.","severity":"gotcha","affected_versions":"<0.15.0"},{"fix":"Update to version 0.15.1 or later to ensure `http.referrer` is correctly parsed. If on older versions, manual parsing would have been required.","message":"The `http.referrer` property was incorrectly missing from the result object in versions prior to 0.15.1, even if present in the playlist. It is now correctly parsed and included.","severity":"gotcha","affected_versions":"<0.15.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For ES Modules, use `import { parse } from 'iptv-playlist-parser'`. For CommonJS, use `const { parse } = require('iptv-playlist-parser')`.","cause":"Incorrect import statement; attempting to use `parse` when it hasn't been correctly imported (e.g., using `import parser from '...'` instead of named import `import { parse } from '...'`).","error":"ReferenceError: parse is not defined"},{"fix":"Upgrade to version 0.12.2 or newer to resolve this parsing issue.","cause":"A bug in earlier versions incorrectly parsed `EXTINF` lines when the channel name itself contained a comma.","error":"Malformed output when channel name contains a comma"},{"fix":"Upgrade to version 0.12.1 or newer to fix the issue with links containing accents.","cause":"A bug in earlier versions caused links with accented characters to be incorrectly handled or ignored during parsing.","error":"Some links containing accents are omitted or incorrectly parsed"},{"fix":"Update to version 0.15.2 or newer to ensure correct handling of all common line ending formats.","cause":"Prior to v0.15.2, the parser had issues correctly handling Windows-style CRLF (Carriage Return Line Feed) line endings, potentially leading to incomplete or incorrect parsing.","error":"Incorrect parsing of CRLF line endings leading to malformed results"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}