Configuration
fetchit is designed to be flexible out of the box while giving you full control over every aspect of its behaviour. You can configure it through a JSON config file, environment variables, or CLI flags — each layer overriding the one below it. This page documents every configuration option, the environment variables that map to them, the directory layout, and how fetchit integrates with yt-dlp and ffmpeg.
Configuration File
fetchit reads its persistent configuration from a JSON file located at ~/.config/fetchit/config.json. This file is optional — if it does not exist, fetchit falls back to built-in defaults. You can also specify a custom config directory via the FETCHIT_CONFIG_DIR environment variable, which changes where fetchit looks for this file.
The file must be valid JSON with a top-level object. Unknown keys are silently ignored, so you can safely keep deprecated options when upgrading. Boolean values must be true or false (not strings). Null values explicitly unset a field and cause fetchit to fall through to the default.
Here is an example configuration file with every available option:
{
"theme": "auto",
"concurrency": 3,
"output": "~/Downloads",
"ytdlpPath": null,
"ffmpegPath": null,
"cookiesFromBrowser": null,
"defaultQuality": null
}Each field maps directly to a CLI flag and an environment variable. The table below describes them in detail.
Options
| Option | Type | Default | Description |
|---|---|---|---|
| theme | string | "auto" | Theme for the TUI. Accepts "auto" (follows system preference), "light", or "dark". When set to "auto", fetchit reads the OS-level color scheme and switches between light and dark palettes accordingly. |
| concurrency | number | 3 | Maximum number of parallel fragment downloads. Higher values (8–16) can speed up downloads on fast connections but consume more memory and CPU. Lower values (1–2) are gentler on limited bandwidth. The default of 3 is a safe starting point for most connections. |
| output | string | "~/Downloads" | Default output directory for downloaded files. Supports the tilde (~) shortcut for the user home directory. Relative paths are resolved from the current working directory. This path is used when no -o / --output flag is provided. |
| ytdlpPath | string | null | Absolute path to a custom yt-dlp binary. When set, fetchit uses this binary instead of the auto-managed copy at ~/.fetchit/bin/yt-dlp. Useful for pinning a specific yt-dlp version or using a system-wide installation. Set to null to use the bundled copy. |
| ffmpegPath | string | null | Absolute path to a custom ffmpeg binary. If set, fetchit passes this location to yt-dlp for merging streams and transcoding. Set to null to let fetchit search PATH and common installation directories automatically. |
| cookiesFromBrowser | string | null | Name of the browser to extract cookies from. Accepts "firefox", "chrome", "chromium", "edge", "brave", "opera", and "safari". Cookies enable access to private videos, age-restricted content, and premium-quality streams. Set to null to disable browser cookie extraction. Firefox is recommended on Windows because it stores cookies in plaintext SQLite — Chrome and Edge encrypt them with platform-level keys that yt-dlp may not be able to decrypt. |
| defaultQuality | string | null | Default quality to use when no quality argument or --best / --mp3 flag is provided. Accepts resolution keywords like "1080p", "720p", "480p", or special values "best" and "mp3". When null, fetchit prompts the user in TUI mode or defaults to "best" in non-interactive mode. |
Environment Variables
Every configuration option can be set via an environment variable with the FETCHIT_ prefix. Environment variables sit above the config file in the precedence hierarchy but below CLI flags, making them ideal for CI/CD pipelines, Docker containers, and shared development environments where you want to override defaults without touching a config file.
Boolean-like environment variables (those that enable or disable a feature) accept the values 1, true, yes, and on (all case-insensitive). Any other value — including an empty string or the variable being unset — is treated as false.
| Variable | Overrides | Description |
|---|---|---|
| FETCHIT_THEME | theme | Default theme for the TUI. Accepts "auto", "light", or "dark". Overrides the theme field in config.json when no --theme flag is passed. |
| FETCHIT_CONCURRENCY | concurrency | Default number of parallel fragment downloads. Must be a positive integer. Overrides the concurrency field in config.json when no --concurrency flag is passed. |
| FETCHIT_OUTPUT | output | Default output directory. Overrides the output field in config.json when no -o / --output flag is passed. Supports tilde expansion. |
| FETCHIT_YTDLP_PATH | ytdlpPath | Path to a custom yt-dlp binary. If set, fetchit uses this binary instead of the auto-managed copy. Takes precedence over the ytdlpPath field in config.json. |
| FETCHIT_FFMPEG_PATH | ffmpegPath | Path to a custom ffmpeg binary. If set, fetchit passes this location to yt-dlp. Takes precedence over the ffmpegPath field in config.json. |
| FETCHIT_COOKIES_BROWSER | cookiesFromBrowser | Name of the browser to extract cookies from. Overrides the cookiesFromBrowser field in config.json. Supported: firefox, chrome, chromium, edge, brave, opera, safari. |
| FETCHIT_CONFIG_DIR | — | Custom directory for the configuration file. When set, fetchit reads config.json from this directory instead of ~/.config/fetchit/. This is useful for portable setups, testing, or when you want to keep configuration alongside a project. |
| FETCHIT_HOME | — | Custom data directory. When set, fetchit uses this directory instead of ~/.local/share/fetchit/ (or the platform equivalent) for storing runtime data such as the auto-downloaded yt-dlp binary and cache files. |
Two of these variables — FETCHIT_CONFIG_DIR and FETCHIT_HOME — do not correspond to a config file field because they control where fetchit looks for configuration and stores data, rather than their values. They are read early during startup, before the config file is parsed.
Configuration Precedence
fetchit resolves its effective configuration using a layered precedence model. Each layer can override the one below it. When a value is not set at a given layer, fetchit looks at the next layer down. This is a common pattern in CLI tools and gives you fine-grained control without requiring you to specify every option every time.
The precedence hierarchy, from highest to lowest priority, is:
- CLI flags — Highest priority. Any flag passed on the command line overrides all other sources. If you pass
--concurrency 8, that value is used regardless of what the config file or environment variables say. Not every option has a CLI flag; options likeytdlpPathare only configurable via the config file or environment variables. - Environment variables — The
FETCHIT_*variables are checked next. They override the config file but are overridden by CLI flags. This layer is especially useful in CI/CD where you want to inject configuration without modifying files. - Config file — The JSON file at
~/.config/fetchit/config.json(or the path specified byFETCHIT_CONFIG_DIR) provides persistent defaults. Values from this file are used when neither a CLI flag nor an environment variable is supplied for a given option. - Built-in defaults — The fallback when no value is found in any of the above layers. These are hardcoded in fetchit and provide sensible defaults for a typical user: theme auto, concurrency 3, output ~/Downloads, and so on.
This layered approach means you can set your preferred theme and output directory in the config file once, override concurrency via an environment variable in a specific terminal session, and then override the output directory for a single download via the -o flag — all without changing the config file.
Implementation note: fetchit evaluates environment variables and CLI flags using their string representations, not their config-file equivalents. This means that if you setFETCHIT_CONCURRENCY=8, it is treated as an override of the default and the config file value — it does not merge with the config file value. The same applies to CLI flags:--concurrency 8completely replaces any concurrency setting from lower layers.
Data Directories
fetchit uses several directories to store configuration, runtime data, cache files, and download history. These follow the XDG Base Directory specification on Linux and macOS, with sensible equivalents on Windows. You can override the base locations using FETCHIT_CONFIG_DIR and FETCHIT_HOME.
Configuration directory
Stores the user configuration file. On Linux and macOS, this is ~/.config/fetchit/. On Windows, it is %APPDATA%\fetchit\ (typically C:\Users\<user>\AppData\Roaming\fetchit). This directory contains:
config.json— The main configuration file with all user preferences.history.json— A JSON array of recently downloaded URLs and their metadata. Used by the TUI for URL autocomplete and the--from-historyflag. This file is managed automatically; you can delete it to clear your download history without affecting other settings.
Data directory
Stores runtime data that is not configuration but persists across sessions. On Linux, this is ~/.local/share/fetchit/. On macOS, it is ~/Library/Application Support/fetchit/. On Windows, it is %LOCALAPPDATA%\fetchit\ (typically C:\Users\<user>\AppData\Local\fetchit). This directory contains:
bin/yt-dlp(orbin/yt-dlp.exeon Windows) — The auto-downloaded yt-dlp engine. This binary is managed by fetchit and updated viafetchit update.- Platform-specific metadata files used by yt-dlp for persistent storage, such as archive files and download tracker databases.
Cache directory
Stores temporary data that can be safely deleted. On Linux and macOS, this is ~/.cache/fetchit/. On Windows, it is %LOCALAPPDATA%\fetchit\cache\. This directory contains:
- Fragment cache — Partial download fragments that are being assembled into the final file. These are cleaned up automatically after a successful download.
- yt-dlp cache — yt-dlp maintains an internal cache for format lookups and player extraction, stored in a subdirectory here.
- Thumbnail cache — Thumbnails downloaded for display in the TUI, if applicable.
The cache directory can be cleared at any time without data loss. Run fetchit doctor --clean-cache or delete the directory manually.
History file
The download history is stored at ~/.config/fetchit/history.json (or the platform equivalent). It is a JSON array of objects, each containing the URL, title, quality, and timestamp of a completed download. The TUI reads this file to provide URL suggestions and the --from-history flag allows you to re-download a recent video by its index in the history.
The history file is capped at 500 entries by default. When the cap is reached, the oldest entries are trimmed. You can disable history entirely by setting FETCHIT_NO_HISTORY=1 or by adding "noHistory": true to the config file.
FETCHIT_HOME to redirect the data directory, note that the config directory is not affected — it is controlled separately by FETCHIT_CONFIG_DIR. This separation lets you keep configuration in a version-controlled location (e.g., a dotfiles repository) while storing bulky runtime data elsewhere.yt-dlp Integration
fetchit is not a downloader itself — it delegates all actual downloading to yt-dlp, the well-known command-line program for downloading videos from YouTube and hundreds of other sites. fetchit acts as a friendly frontend: it manages the yt-dlp binary, constructs the appropriate command-line arguments, parses the output, and presents a polished TUI or CLI interface.
Auto-download on first run
When you run fetchit for the first time, it checks whether a compatible yt-dlp binary is available. If none is found, fetchit automatically downloads the latest stable release of yt-dlp from GitHub and places it at ~/.local/share/fetchit/bin/yt-dlp (or the platform equivalent under FETCHIT_HOME). This binary is used for all subsequent downloads unless overridden by ytdlpPath or FETCHIT_YTDLP_PATH.
The auto-download happens in the background during startup and typically completes within a few seconds on a fast connection. If the download fails (e.g., no network access), fetchit prints a warning and falls back to any yt-dlp found on PATH. You can trigger a manual re-download with fetchit update.
Updating yt-dlp
YouTube and other sites frequently change their APIs and player code, which means yt-dlp must be updated regularly to stay functional. fetchit provides a dedicated command to update the managed yt-dlp binary:
fetchit update
This command downloads the latest yt-dlp release, verifies its integrity via SHA-256 checksum, replaces the old binary atomically (the old binary is renamed to yt-dlp.old as a backup), and prints the new version number. If you use a custom yt-dlp path (ytdlpPath), the update command skips the managed copy and prints a reminder to update your custom binary manually.
fetchit does not auto-update yt-dlp on every run. You are responsible for running fetchit update periodically. We recommend updating at least once a month, or whenever you encounter download failures that mention "This video is unavailable" or "Sign in to confirm your age" — these are often signs that yt-dlp is out of date.
Custom yt-dlp path
If you prefer to manage yt-dlp yourself — for example, you have a system-wide installation via your package manager, or you need a specific version for compatibility — you can tell fetchit to use a custom binary:
- Config file: Set
"ytdlpPath": "/usr/local/bin/yt-dlp"inconfig.json. - Environment variable: Set
FETCHIT_YTDLP_PATH=/usr/local/bin/yt-dlp.
When a custom path is configured, fetchit uses that binary directly and skips the managed copy. The fetchit update command will detect the custom path and skip the update, printing a notice instead. This is particularly useful in CI/CD pipelines where you want to pin a specific yt-dlp version for reproducibility.
Fallback behaviour
If the configured yt-dlp binary does not exist or fails to execute, fetchit attempts these fallbacks in order:
- The managed copy at
~/.local/share/fetchit/bin/yt-dlp. - Any
yt-dlpfound on the system PATH. - A prompt to download yt-dlp automatically. If the user confirms, the download proceeds and fetchit retries the operation.
If all fallbacks fail, fetchit exits with an error message explaining that yt-dlp could not be located and provides instructions for manual installation.
ffmpeg Integration
ffmpeg is required for several fetchit features: merging separate video and audio streams into a single file, extracting audio and transcoding to MP3, embedding chapter markers, and clipping video segments by timestamp. Unlike yt-dlp, fetchit does not bundle or auto-download ffmpeg — you must install it separately.
Detection logic
When fetchit needs ffmpeg (for example, when downloading 1080p video, which on YouTube is typically delivered as separate video-only and audio-only streams), it searches for an ffmpeg binary in the following order:
- The path specified by
ffmpegPathin the config file orFETCHIT_FFMPEG_PATHin the environment. - Any
ffmpegorffmpeg.exefound on the system PATH. - Common installation directories:
/usr/bin/ffmpeg,/usr/local/bin/ffmpeg,/opt/homebrew/bin/ffmpeg(macOS ARM),C:\tools\ffmpeg.exe,C:\ProgramData\chocolatey\bin\ffmpeg.exe, and%LOCALAPPDATA%\Microsoft\WinGet\packages\ffmpeg.
If ffmpeg is not found and the requested operation requires it, fetchit prints a clear error message with installation instructions for your platform. Downloads that do not require ffmpeg (e.g., 720p YouTube videos that come as a single multiplexed stream, or audio-only downloads with the --ytdl-args "-x --audio-format mp3" fallback) proceed without it.
What requires ffmpeg
- Stream merging: When a video is downloaded in a resolution that requires merging a separate video-only stream and audio-only stream (typical for YouTube 1080p and above), ffmpeg is used to multiplex them into a single MP4 or MKV file.
- MP3 extraction: The
--mp3flag andmp3quality keyword use ffmpeg to transcode the downloaded audio stream to MP3 format. - Chapter embedding: The
--chaptersflag uses ffmpeg to embed YouTube chapter markers into the output file. - Timestamp clipping: The
--fromand--toflags use ffmpeg to cut the downloaded video to the specified time range without re-encoding (fast seek).
Installing ffmpeg
Installation instructions vary by platform. Here are the recommended methods:
| Platform | Command / Method |
|---|---|
| macOS (Homebrew) | brew install ffmpeg |
| Ubuntu / Debian | sudo apt install ffmpeg |
| Fedora / RHEL | sudo dnf install ffmpeg |
| Arch Linux | sudo pacman -S ffmpeg |
| Windows (Chocolatey) | choco install ffmpeg |
| Windows (WinGet) | winget install ffmpeg |
| Windows (manual) | Download from https://ffmpeg.org/download.html and add to PATH |
| Docker | RUN apt update && apt install -y ffmpeg (Debian-based images) |
After installing, run ffmpeg -version to verify the installation. Then run fetchit doctor to confirm fetchit detects ffmpeg correctly. If you installed ffmpeg to a non-standard location, set ffmpegPath in the config file or FETCHIT_FFMPEG_PATH in the environment.
Custom ffmpeg path
Just like yt-dlp, you can point fetchit to a custom ffmpeg binary. This is useful if you have a specific build (e.g., a static build for portability, or a version with specific codec support):
- Config file: Set
"ffmpegPath": "/opt/ffmpeg-custom/bin/ffmpeg"inconfig.json. - Environment variable: Set
FETCHIT_FFMPEG_PATH=/opt/ffmpeg-custom/bin/ffmpeg.
When a custom path is set, fetchit uses it directly and skips all detection logic. If the binary at the custom path does not exist or is not executable, fetchit prints an error and does not fall back to other locations — this is intentional so that misconfigured paths are surfaced immediately rather than silently ignored.
Custom Output Templates
fetchit uses yt-dlp's powerful output template system to name downloaded files. By default, downloaded files are saved using the following pattern:
~/Downloads/%(title)s.%(ext)s
This produces files like ~/Downloads/Never Gonna Give You Up.mp4. The %(title)s placeholder expands to the video title, and %(ext)s expands to the appropriate file extension (mp4, mkv, webm, mp3, etc.).
You can customise this pattern using yt-dlp's full set of template variables. Pass your custom template via the -o / --output flag:
# Include video ID and upload date fetchit -o "~/Downloads/%(upload_date)s - %(id)s - %(title)s.%(ext)s" https://... # Organise by uploader fetchit -o "~/Downloads/%(uploader)s/%(title)s.%(ext)s" https://... # Limit title length (useful on Windows where paths are limited to 260 characters) fetchit -o "~/Downloads/%(title).100B.%(ext)s" https://... # Use a flat numeric index fetchit -o "~/Downloads/video_%(autonumber)03d.%(ext)s" https://...
Playlist subfolder behaviour
When downloading a playlist, fetchit organises files into subdirectories named after the playlist title by default. The effective output pattern becomes:
~/Downloads/%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s
This creates a folder structure like:
~/Downloads/
My Playlist/
1 - First Video.mp4
2 - Second Video.mp4
3 - Third Video.mp4The playlist subfolder behaviour can be disabled with the --flat flag. When --flat is passed, all files are saved directly into the output directory regardless of playlist membership:
fetchit --flat https://youtube.com/playlist?list=...
You can also override the playlist template entirely by providing a custom output pattern that includes (or excludes) playlist variables:
# Flatten but still include playlist index in the filename fetchit -o "~/Downloads/%(playlist_title)s - %(playlist_index)s - %(title)s.%(ext)s" --flat https://... # Custom subfolder structure by playlist ID instead of title fetchit -o "~/Downloads/%(playlist_id)s/%(title)s.%(ext)s" https://...
Supported template variables
fetchit supports all yt-dlp output template variables. The most commonly used ones are:
| Variable | Description | Example |
|---|---|---|
| %(title)s | Video title (may contain characters invalid on some filesystems) | Never Gonna Give You Up |
| %(id)s | Video ID from the URL | dQw4w9WgXcQ |
| %(ext)s | Output file extension | mp4 |
| %(uploader)s | Channel / uploader name | Rick Astley |
| %(upload_date)s | Upload date in YYYYMMDD format | 20091025 |
| %(playlist_title)s | Playlist title (empty for single videos) | My Mix |
| %(playlist_id)s | Playlist ID | PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf |
| %(playlist_index)s | Numeric index within playlist (1-based) | 1 |
| %(playlist_count)s | Total number of items in the playlist | 42 |
| %(autonumber)s | Auto-incrementing number across all downloads | 00001 |
| %(duration)s | Video duration in seconds | 212 |
| %(height)s | Height of the downloaded video stream | 1080 |
| %(resolution)s | Resolution string (width x height) | 1920x1080 |
| %(fps)s | Frame rate of the video stream | 30 |
For the complete list, see the yt-dlp output template documentation. Note that characters that are illegal on your filesystem (such as /, \0, or : on Windows) are automatically sanitised by yt-dlp and replaced with underscores.
%(title).100B syntax to truncate the title to 100 bytes, or enable long path support via Group Policy (Computer Configuration > Administrative Templates > System > Filesystem > Enable Win32 long paths).Configuring the TUI
In addition to the options described above, the TUI has a few behaviour flags that can be set in the config file or via CLI flags:
| Option / Flag | Type | Default | Description |
|---|---|---|---|
| noHistory | boolean | false | If true, do not record download history. This can also be set via FETCHIT_NO_HISTORY=1. |
These options are additional fields you can include at the top level of config.json alongside the ones in the Options table above.
Validating your configuration
After editing your config file or setting environment variables, you can validate everything is correct by running:
fetchit doctor
The doctor command reads your configuration, checks for common issues, verifies that yt-dlp and ffmpeg are accessible (and that the configured custom paths exist), and prints a summary of all resolved settings. This is the fastest way to confirm that your changes have taken effect and that your setup is healthy.
You can also print the effective configuration for inspection:
fetchit --verbose doctor
This displays the full merged configuration object, showing which value each option resolved to and which layer it came from.
Example configurations
Minimal setup
If you only want to change the output directory and set a default quality, your config file can be as small as:
{
"output": "~/Videos/fetchit",
"defaultQuality": "1080p"
}Power user setup
An example that uses custom binary paths, dark theme, high concurrency, and browser cookies:
{
"theme": "dark",
"concurrency": 8,
"output": "~/Movies/fetchit",
"ytdlpPath": "/usr/local/bin/yt-dlp",
"ffmpegPath": "/opt/homebrew/bin/ffmpeg",
"cookiesFromBrowser": "firefox",
"defaultQuality": "best",
"windowed": true,
"logLevel": "info",
"noHistory": false
}Windows setup
On Windows, paths use backslashes and the default data directories differ:
{
"theme": "auto",
"concurrency": 4,
"output": "C:\Users\<user>\Videos\fetchit",
"ytdlpPath": "C:\tools\yt-dlp\yt-dlp.exe",
"ffmpegPath": "C:\tools\ffmpeg\bin\ffmpeg.exe",
"cookiesFromBrowser": "firefox",
"defaultQuality": "720p"
}Note that on Windows, backslashes in JSON must be escaped as \\. You can also use forward slashes — Windows accepts them in most contexts.
Next steps
With your configuration in place, explore the CLI Reference for the full list of flags and arguments, or dive into Interactive Mode to learn how to use the TUI efficiently. Run fetchit doctor anytime to verify your setup is healthy.