🌊 Nami
An open-source CLI media downloader for Instagram, TikTok, Facebook, and X
Nami is a lightweight, open-source media downloader designed for seamless batch extraction across social platforms. Combining gallery-dl and yt-dlp with an interactive Rich terminal interface and scriptable CLI workflows, Nami automates deduplication, rate-limit retries, and browser cookie handling.
Installation • Quickstart • Supported Platforms • CLI Commands • Configuration • Diagnostics • Troubleshooting
Features
- Multi-Platform Batch Downloads: Extract high-resolution photos, videos, reels, posts, stories, and highlights.
- Dual-Engine Architecture: Intelligently routes tasks between
gallery-dlandyt-dlpwith automatic fallback on extractor failures. - Interactive & Headless Modes: Run interactively with an intuitive terminal UI or integrate into headless pipelines with dedicated CLI subcommands and
--jsonoutput. - Smart Anti-Duplicate Archiving: Maintains per-target
archive.txtrecords to avoid redundant re-downloads, with safearchive resetmanagement. - Flexible Authentication: Supports Netscape cookie files, anonymous fallbacks, and direct browser cookie extraction (
--cookies-from-browser). - Resilient Retry & Failure Classification: Classifies auth, cookie, rate-limit, network, dependency, not-found, extractor, and timeout failures with exponential jittered backoff.
- Built-in System Doctor: Run
nami doctorto verify local binaries, browser installations, cookie permissions, and workspace health without network calls.
Supported Platforms
| Platform | Photos / Posts | Videos / Reels | Stories | Highlights | Auth Support | Primary Engine |
|---|---|---|---|---|---|---|
| Included | Included | Included | Included | Netscape Cookie / Anonymous | gallery-dl / yt-dlp |
|
| TikTok | Limited by upstream | Included | N/A | N/A | Browser DB / Netscape Cookie | yt-dlp / gallery-dl |
| Limited by upstream | Included | N/A | N/A | Netscape Cookie / Anonymous | gallery-dl / yt-dlp |
|
| X (Twitter) | Limited by upstream | Included | N/A | N/A | Netscape Cookie / Anonymous | gallery-dl / yt-dlp |
[!NOTE] Unsupported media combinations are reported as unsupported operations instead of silently failing or being treated as successful downloads.
Installation
Install nami directly via pip:
python -m pip install nami
Runtime dependencies (rich, gallery-dl, yt-dlp) are automatically installed.
To upgrade to the latest release:
python -m pip install --upgrade nami
Nami requires Python 3.10 or newer.
Quickstart
1. Interactive Mode
Run nami without arguments to launch the interactive terminal UI:
nami
┌──────────────────────── Nami ────────────────────────┐
│ What do you want to download? │
│ │
│ 1 Photos only │
│ 2 Videos only │
│ 3 Stories only │
│ 4 Highlights only │
│ 5 Photos + Videos │
│ 6 Stories + Highlights │
│ 7 All │
│ 8 Settings │
│ 0 Exit │
│ │
│ Save: ~/Nami/downloads │
└──────────────────────────────────────────────────────┘
On first launch, Nami guides you through workspace initialization. Workspace setup is explicit and never creates files as hidden import-time side effects.
2. Workspace Layout
Nami organizes downloads, cookie files, and target profile lists cleanly:
Nami/
├── downloads/ # Extracted media organized by platform, account & kind
├── cookies/ # Optional Netscape cookie files (*_cookies.txt)
└── profiles/ # Target profile URLs (*_profiles.txt)
├── facebook_profiles.txt
├── instagram_profiles.txt
├── tiktok_profiles.txt
└── x_profiles.txt
CLI Commands Reference
Nami provides a full suite of scriptable subcommands for headless pipelines and automation:
nami setup
Initialize a Nami workspace directory structure and configuration:
# Initialize workspace under current directory
nami setup --root .
# Initialize with template cookie files
nami setup --root /path/to/workspace --cookie-templates
# Output JSON report
nami setup --root . --json
nami download
Download specific target URLs or batch profiles:
# Download direct URLs
nami download https://www.instagram.com/p/DAEXAMPLE123/ https://x.com/OpenAI/status/123456
# Filter by media kinds (photos, videos, stories, highlights, all)
nami download https://www.instagram.com/example/ --media photos,videos
# Force platform inference when URL is ambiguous
nami download https://x.com/example --platform x --media videos
# Batch download all configured profile files
nami download --profiles
# Filter profile downloads by platform and media kinds
nami download --profiles --platform instagram --media stories,highlights
# Machine-readable JSON output
nami download --profiles --media all --json
nami doctor
Inspect system health, engine availability, browser installations, and workspace configuration without network calls:
nami doctor
nami doctor --json
nami config
Inspect and update persistent configuration settings:
# Show all active settings
nami config show
# Get a specific setting value
nami config get browser
nami config get base_dir
# Set a setting value
nami config set browser chrome
nami config set timeout_seconds 600
# Reset a setting to its default/derived value
nami config unset browser
# Machine-readable JSON output
nami config show --json
nami archive reset
Safely manage download tracking archives to enable re-downloading media without deleting archives implicitly:
# Preview archives that would be reset (dry run)
nami archive reset --all --dry-run
# Back up archives for a specific target (creates timestamped .bak files)
nami archive reset --platform instagram --target example --yes
# Filter reset by media kind
nami archive reset --platform instagram --target example --media stories --yes
# Permanently delete matching archives only when intentional
nami archive reset --all --delete --yes
Authentication & Cookies
To access private content, high-resolution stories, or avoid login restrictions:
1. Netscape Cookie Files
Place Netscape-formatted cookie files inside your configured cookies_dir. Nami validates that files contain at least one valid seven-column Netscape cookie row; placeholder files and headers alone are rejected.
Nami recognizes platform-specific cookie filenames such as:
instagram_cookies.txtorinstagram.com_cookies.txttiktok_cookies.txtortiktok.com_cookies.txtfacebook_cookies.txtorfacebook.com_cookies.txtx_cookies.txt,x.com_cookies.txt,twitter_cookies.txt, ortwitter.com_cookies.txt
2. Browser Session Extraction
TikTok can fall back to browser cookie extraction when no valid cookie file is available. Configure your browser via:
nami config set browser brave # Options: brave, chrome, edge, firefox
Note: If the configured browser is currently running, its database may be locked; nami doctor will report this as a warning.
Configuration & Environment Variables
Nami loads configuration in the following order of precedence:
- Environment variables
~/.nami/nami_config.json- Default values based on the user's home directory
| Configuration Key | Environment Variable | Description | Default |
|---|---|---|---|
base_dir |
NAMI_BASE_DIR |
Download output root directory | ~/Nami/downloads |
cookies_dir |
NAMI_COOKIES_DIR |
Netscape cookie files directory | ~/Nami/cookies |
profiles_dir |
NAMI_PROFILES_DIR |
Target profile text files directory | ~/Nami/profiles |
browser |
NAMI_BROWSER |
Browser for automated cookie extraction (brave, chrome, edge, firefox) |
brave |
user_agent |
NAMI_USER_AGENT |
Custom HTTP User-Agent string | Standard Chrome string |
timeout_seconds |
NAMI_TIMEOUT_SECONDS / NAMI_TIMEOUT |
Child engine process execution timeout (seconds) | 1800 |
| — | NAMI_THEME |
Terminal UI theme styling (dark, light, auto) |
dark |
| — | NAMI_SKIP_ENV_CHECK |
Set to 1 to bypass startup binary verification |
0 |
Diagnostics
Run local, read-only system diagnostics:
nami doctor
Doctor checks include:
- Configuration validity and integrity
- Python version compatibility (>= 3.10)
- Importability and versions of runtime dependencies (
rich,gallery-dl,yt-dlp) - Workspace readability and writability
- Configured browser installation and process lock state
- Netscape cookie file validity (detects placeholder/empty files)
- Profile file readability and syntax validation
- Potential
urllib3namespace conflicts - Stale archive lock detection
Exit Codes
Nami returns deterministic exit codes for CI/CD and scripting pipelines:
| Exit Code | Meaning | Description |
|---|---|---|
| 0 | Success | All requested download or management operations completed successfully |
| 1 | Failure | One or more download operations failed after retry/fallback attempts |
| 2 | Invalid Input | Invalid CLI argument, unparseable profile URL, or corrupt configuration |
| 3 | Partial / Unsupported | Partial results, warnings, or unsupported platform/media combinations |
| 4 | No Results | Extractor completed successfully but found 0 downloadable items |
| 130 | Cancelled | Execution interrupted via SIGINT (Ctrl+C) |
Development & Testing
Clone the repository and install development dependencies in an editable environment:
git clone https://github.com/OpenSelena/nami.git
cd nami
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
Running Checks & Tests
# Run test suite with pytest
PYTHONPATH=src python -m pytest -q
# Run Ruff lint and format checks
python -m ruff check src tests
python -m ruff format --check src tests
# Build and verify distribution package
python -m build
python -m twine check dist/*
check-wheel-contents dist/*.whl
The test suite runs completely offline without making external network calls.
Troubleshooting
- Check diagnostics first: Run
nami doctorto get immediate actionable remediation steps. - Import issues during testing: If
pytestimports an old installed copy of Nami, run withPYTHONPATH=srcor reinstall editable withpython -m pip install -e ".[dev]". - Cookie authentication failures: Ensure exported Netscape cookie files contain genuine 7-column rows and not just headers/comments.
- Browser database locked: If TikTok browser cookie extraction fails, close all running instances of your configured browser and retry.
- Download timeouts: If downloads of large profiles or playlists time out, increase the timeout limit via
nami config set timeout_seconds 3600. - Re-downloading existing media: Use
nami archive resetto clear or back up tracking archives rather than deleting files manually.
License
Distributed under the MIT License. Developed and maintained by Igect under OpenSelena.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nami-5.0.2.tar.gz.
File metadata
- Download URL: nami-5.0.2.tar.gz
- Upload date:
- Size: 68.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d9557d6df6534c01afb2b0f7ce0757a435c2a5d39236475b13041510f591333
|
|
| MD5 |
230c66a07f996a10492a732311251381
|
|
| BLAKE2b-256 |
c39a142fc85d811e984334a4e69e9f9109bd0554b9c163803374ef806823422c
|
Provenance
The following attestation bundles were made for nami-5.0.2.tar.gz:
Publisher:
publish.yml on OpenSelena/nami
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nami-5.0.2.tar.gz -
Subject digest:
6d9557d6df6534c01afb2b0f7ce0757a435c2a5d39236475b13041510f591333 - Sigstore transparency entry: 2498813836
- Sigstore integration time:
-
Permalink:
OpenSelena/nami@325d42a9a3e54939a2c4ee3a9ef8488c2c40d347 -
Branch / Tag:
refs/tags/v5.0.2 - Owner: https://github.com/OpenSelena
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@325d42a9a3e54939a2c4ee3a9ef8488c2c40d347 -
Trigger Event:
release
-
Statement type:
File details
Details for the file nami-5.0.2-py3-none-any.whl.
File metadata
- Download URL: nami-5.0.2-py3-none-any.whl
- Upload date:
- Size: 54.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60fe075a3230a35b52745ebe0c5df04bdbd94f73029121b5db7affe7e33c8adf
|
|
| MD5 |
748962ef24604c2afb94f29ff73e6938
|
|
| BLAKE2b-256 |
5b8eb54ad595a74ecae685e0bc214b18e6ac73937360bc141e22abc83bf684c8
|
Provenance
The following attestation bundles were made for nami-5.0.2-py3-none-any.whl:
Publisher:
publish.yml on OpenSelena/nami
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nami-5.0.2-py3-none-any.whl -
Subject digest:
60fe075a3230a35b52745ebe0c5df04bdbd94f73029121b5db7affe7e33c8adf - Sigstore transparency entry: 2498813851
- Sigstore integration time:
-
Permalink:
OpenSelena/nami@325d42a9a3e54939a2c4ee3a9ef8488c2c40d347 -
Branch / Tag:
refs/tags/v5.0.2 - Owner: https://github.com/OpenSelena
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@325d42a9a3e54939a2c4ee3a9ef8488c2c40d347 -
Trigger Event:
release
-
Statement type: