# How to Export IPTV Playlists to Different Formats: JSON, M3U, and API Data

> Easily export IPTV playlists to JSON, M3U, and API formats using iptv-org/iptv npm commands. Convert raw stream data into readable, machine-friendly files for seamless integration.

- Repository: [iptv-org/iptv](https://github.com/iptv-org/iptv)
- Tags: how-to-guide
- Published: 2026-02-25

---

**The iptv-org/iptv repository provides three npm commands—`playlist:export` for JSON, `playlist:format` for normalized M3U, and `playlist:generate` for categorized index files—that convert raw stream data into machine-readable formats.**

The iptv-org/iptv project maintains a massive collection of publicly available IPTV streams and offers a TypeScript-based CLI toolkit to export these playlists into structured formats. Whether you need a JSON catalogue for API consumption or deduplicated M3U files organized by country, the automation scripts in `scripts/commands/playlist/` handle the entire transformation pipeline.

## Export IPTV Playlists to JSON for API Consumption

The JSON export produces [`.api/streams.json`](https://github.com/iptv-org/iptv/blob/main/.api/streams.json), a machine-readable catalogue containing normalized stream metadata. This format is ideal for downstream applications that need to query channel data programmatically rather than parsing raw M3U files.

### Using the CLI Export Command

Run the built-in export command to generate the JSON API file:

```bash
npm run playlist:export

```

This command executes [`scripts/commands/playlist/export.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/export.ts), which performs the following operations:

1. Loads reference data (countries, categories, channels) via `loadData()` from [`scripts/api.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/api.ts).
2. Discovers all `*.m3u` files in the streams directory using the `Storage` class.
3. Parses each file into a `Collection<Stream>` using `PlaylistParser` from [`scripts/core/playlistParser.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/core/playlistParser.ts).
4. Serializes the collection to JSON using the `Stream.toObject()` method defined in [`scripts/models/stream.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/models/stream.ts).

You can override default paths using environment variables for CI pipelines or custom workflows:

```bash
DATA_DIR=tmp/data STREAMS_DIR=tmp/streams API_DIR=tmp/.api npm run playlist:export

```

### Programmatic Export with TypeScript

For custom integrations, import the core classes directly to export IPTV playlists programmatically:

```typescript
import { Storage } from '@freearhey/storage-js'
import { PlaylistParser } from './scripts/core'
import { loadData } from './scripts/api'
import { Stream } from './scripts/models'

async function exportJson() {
  await loadData()
  const storage = new Storage('streams')
  const parser = new PlaylistParser({ storage })
  const files = await storage.list('**/*.m3u')
  const collection = await parser.parse(files)

  const json = collection
    .sortBy((s: Stream) => s.getId())
    .map((s: Stream) => s.toObject())
    .toJSON()

  console.log(json)
}
exportJson()

```

The `toObject()` method in [`scripts/models/stream.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/models/stream.ts) handles the transformation of stream instances into plain objects suitable for JSON serialization.

## Normalize and Reformat M3U Playlists

The `playlist:format` command cleans raw M3U files by normalizing URLs, deduplicating entries, and repairing metadata. This ensures consistent `group-title`, `tvg-logo`, and `tvg-id` attributes across all playlists.

Run the formatter via npm:

```bash
npm run playlist:format

```

Or target specific files:

```bash
npm run playlist:format mycountry.m3u other.m3u

```

The script [`scripts/commands/playlist/format.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/format.ts) executes an eight-step pipeline:

1. **Loads API reference data** via `loadData()`.
2. **Parses M3U files** into a typed collection using `PlaylistParser`.
3. **Normalizes URLs** using `Stream.normalizeURL()` from [`scripts/utils.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/utils.ts).
4. **Removes duplicate streams** by comparing normalized URLs.
5. **Repairs missing identifiers** including `tvg-id`, `channel`, and `feed` attributes.
6. **Infers missing feed IDs** where possible based on channel metadata.
7. **Sorts streams** by title, resolution, label, and URL for deterministic output.
8. **Writes cleaned files** back to the streams directory using `Storage.save()`.

To change the output location, modify `STREAMS_DIR` in [`scripts/constants.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/constants.ts) or set the `STREAMS_DIR` environment variable.

## Generate Canonical Index Playlists by Category

The `playlist:generate` command creates a comprehensive set of index playlists that group streams by geography, language, and category. This is the primary method for exporting IPTV playlists into consumable, filtered M3U files.

Execute the generator:

```bash
npm run playlist:generate

```

This runs [`scripts/commands/playlist/generate.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/generate.ts), which orchestrates generator classes located in `scripts/generators/*`. The command produces several index files:

- `index.m3u` — Alphabetical list of all available streams.
- `index.country.m3u` — Individual files per country (e.g., `us.m3u`, `fr.m3u`).
- `index.language.m3u` — Playlists grouped by broadcast language.
- `index.category.m3u` — Streams organized by content category.

The generation process removes duplicate IDs, sorts streams by quality and name, and logs progress to `logs/generators.log`.

## Core Architecture and Key Files

Understanding the following source files helps when customizing export behavior or debugging the pipeline:

- **[`scripts/constants.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/constants.ts)** — Centralizes path definitions (`STREAMS_DIR`, `API_DIR`) and configuration constants.
- **[`scripts/api.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/api.ts)** — Implements `loadData()`, which fetches reference datasets (countries, categories, channels) required for normalization.
- **[`scripts/core/playlistParser.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/core/playlistParser.ts)** — Contains the `PlaylistParser` class that transforms raw M3U text into `Collection<Stream>` objects.
- **[`scripts/models/stream.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/models/stream.ts)** — Defines the `Stream` domain model with conversion methods `toObject()` and `toString()`.
- **[`scripts/utils.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/utils.ts)** — Provides utility functions including URL normalization logic used during the export process.

## End-to-End Workflow Example

Complete the following sequence to refresh, clean, export, and categorize your IPTV data:

```bash

# 1. Clean and normalize all raw M3U files

npm run playlist:format

# 2. Export the full catalogue as JSON for API consumers

npm run playlist:export

# 3. Generate ready-to-use country and language index files

npm run playlist:generate

```

After execution, the repository contains:

- `streams/*.m3u` — Deduplicated, normalized playlist files.
- [`.api/streams.json`](https://github.com/iptv-org/iptv/blob/main/.api/streams.json) — Machine-readable JSON catalogue.
- `logs/generators.log` — Detailed generation logs for auditing.

## Summary

- **`npm run playlist:export`** generates [`.api/streams.json`](https://github.com/iptv-org/iptv/blob/main/.api/streams.json) via [`scripts/commands/playlist/export.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/export.ts), using `Stream.toObject()` for serialization.
- **`npm run playlist:format`** cleans M3U files via [`scripts/commands/playlist/format.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/format.ts), normalizing URLs with `Stream.normalizeURL()` and deduplicating entries.
- **`npm run playlist:generate`** builds categorized index files via [`scripts/commands/playlist/generate.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/generate.ts), creating country-specific and language-specific M3U outputs.
- **Environment variables** (`DATA_DIR`, `STREAMS_DIR`, `API_DIR`) allow custom directory configurations without modifying source code.
- **Programmatic access** is available by importing `PlaylistParser`, `Storage`, and `loadData()` from the scripts directory.

## Frequently Asked Questions

### What is the difference between playlist:format and playlist:generate?

**`playlist:format`** cleans existing M3U files by normalizing URLs, removing duplicates, and repairing metadata, writing the results back to the same `streams/` directory. **`playlist:generate`** creates new index files (like `index.country.m3u`) that aggregate streams into categorized playlists for end-user consumption. Use `format` to clean data, then `generate` to create distribution-ready files.

### How do I export IPTV playlists to JSON for custom applications?

Import `PlaylistParser` from `scripts/core`, instantiate it with a `Storage` object pointing to your streams directory, call `parser.parse(files)` to get a `Collection<Stream>`, then use `.map(s => s.toObject()).toJSON()` to produce the JSON string. The [`export.ts`](https://github.com/iptv-org/iptv/blob/main/export.ts) command implements this exact workflow for the CLI.

### Can I specify custom directories for the exported files?

Yes. Set the `DATA_DIR`, `STREAMS_DIR`, and `API_DIR` environment variables before running any command, or modify the constants in [`scripts/constants.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/constants.ts). For example: `STREAMS_DIR=custom/streams npm run playlist:format` processes files from `custom/streams` instead of the default location.

### Which script handles URL normalization during the export process?

URL normalization occurs in `Stream.normalizeURL()` within [`scripts/utils.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/utils.ts), which is invoked by [`scripts/commands/playlist/format.ts`](https://github.com/iptv-org/iptv/blob/main/scripts/commands/playlist/format.ts) during the formatting phase. This ensures consistent stream addresses before deduplication and JSON serialization, preventing the same channel from appearing multiple times with slightly different URLs.