A Media button in the Discord channel header that opens a browsable, searchable, filterable gallery of every image, video, GIF, file and link in the channel, the DM, or the whole server. Like the media tab on Discord mobile, or a Twitter profile's Media tab — but with real filters and a details view.
┌──────────────────────────────────────────────────────────────────┐
│ #general 📞 📹 📌 👥 🖼️ [ Search... ] │ ← the button
└──────────────────────────────────────────────────────────────────┘
You need Vencord installed first. Then paste one line and wait a couple of minutes.
Windows — Command Prompt or PowerShell:
powershell -c "irm https://raw.githubusercontent.com/destination/mediatab/main/get.ps1 | iex"
macOS / Linux — Terminal:
curl -fsSL https://raw.githubusercontent.com/destination/mediatab/main/get.sh | bashIt installs anything missing, downloads MediaTab, builds it against the latest Vencord, closes Discord, and hooks everything up.
Then in Discord:
- Settings → Vencord → Plugins
- Search MediaTab, switch it on
- Press
Ctrl+R/Cmd+R
A picture icon appears at the top right of any chat, next to the pin.
To update, run the exact same command again. It pulls the latest MediaTab and the latest Vencord and rebuilds both.
Prefer to do it by hand?
git clone https://github.com/destination/mediatab.git
cd mediatab
./scripts/setup.sh # clones Vencord, installs deps, builds
# quit Discord completely, then:
./scripts/install.shUpdate later with ./scripts/update.sh.
Is piping a script into a shell safe?
It's the same pattern rustup, Homebrew and nvm use, and the safety comes from being able to read what you're running. Both scripts are short and deliberately kept that way — open get.sh or get.ps1 and read them first. They need no admin rights and never modify Discord's own files.
If you'd rather not pipe, use the by-hand steps above — they do exactly the same thing.
Details below; if anything goes wrong, jump to Troubleshooting.
- What it does
- Requirements
- Install
- Using it
- Settings
- Updating
- Uninstalling
- Troubleshooting
- Project layout
- Further docs
Three ways in
| Entry point | Where | Default |
|---|---|---|
| Header button | Channel header, next to the pin / member-list icons | on |
| Context menu | Right-click a channel, thread, group DM or user → View Media | on |
| Chat bar button | Next to the message box | off (enable in settings) |
Filter tabs — All · Images · Videos · GIFs · Audio · Files · Links
Filters
- Free-text search over message content
- Author — multi-select, searchable; pre-populated with the channel's participants plus everyone found in the results so far
- Sort — newest first, oldest first, or most relevant
- Scope — this channel, or the entire server (guild channels only)
- Date range — from / to, using native date pickers
- File extension — e.g.
png,mp4,pdf - Pinned only
Three layouts
- Grid — pick how many per row (2, 3, 4, 5, 6, 8, 10) straight from the toolbar, or "Fit to width" with an adjustable tile size. Defaults to 4 per row.
- List — thumbnail plus name, author, channel, timestamp, type and size
- Details — a sortable table; click any column header to sort what's loaded by name, author, type, size, channel or date
Sorting is newest first by default, everywhere.
Per-item actions (on hover)
- ↗ Jump — closes the browser and jumps to the message in the channel
- 🔗 Copy link — copies the media URL
- ⤓ Download — saves the file
Selection and bulk actions — click the checkbox on any tile or row to enter selection mode, then Download all or Copy links for everything selected.
Viewing — clicking an image, GIF, video or sticker opens Discord's own lightbox, loaded with every viewable item in the current result set, so the arrow keys walk through the whole gallery. Files and links open externally.
Other details
- Spoilered media is blurred until hovered (toggleable)
- Infinite scroll, plus an explicit Load more button
- Thumbnails are served resized through
media.discordapp.net, so a grid of 200 items doesn't download 200 full-resolution originals - Rate limits and "server still indexing" responses are retried automatically with the delay Discord asks for
- macOS, Windows or Linux desktop Discord. This is a Vencord plugin; it cannot run on Discord in a normal browser tab.
- Vencord already installed the normal way, from vencord.dev/download. These scripts add a plugin to an existing install; they don't install Vencord for you.
- Node.js 22 or newer and git. On Windows, run the commands in Git Bash rather than PowerShell.
- Custom plugins require building Vencord from source. See below.
Sharing it with someone else: docs/SHARING.md.
No — and it's worth understanding why, because it's the single most common misconception about Vencord.
Vencord compiles plugins into its bundle. Its whole architecture works by
rewriting Discord's own JavaScript as those modules load, and the rewrite rules
have to be present in the bundle before Discord starts. There is no runtime
plugin loader to drop a file into. Settings → Vencord → Plugins is a list of
what was compiled in, with on/off switches — not a folder you can add to.
Drop-in plugin files are BetterDiscord's model. Different mod, different plugin API; this plugin would have to be rewritten for it.
So the only supported route is building Vencord from source once. The good news:
- Your settings, themes and enabled plugins are untouched. They live in
Vencord's data folder, separate from the build, and
scripts/install.shbacks them up anyway before doing anything. - It takes about two minutes and is fully reversible with
scripts/uninstall.sh. - The trade-off: Vencord's built-in auto-updater no longer manages your install.
You update with
./scripts/update.sh, which pulls the latest Vencord, rebuilds, and re-checks the plugin against Discord's current code.
Client mods are against Discord's Terms of Service, though there are no known cases of anyone being banned for using one. This plugin is read-only, automates nothing, and makes the same requests through the same code path as Discord's own search box. The honest, full version — including why "undetectable" isn't a promise anyone can make — is in docs/RULES-AND-RISK.md. Worth five minutes before you install.
Vencord must already be installed the normal way. Then:
git clone https://github.com/destination/mediatab.git
cd mediatab
# 1. clone Vencord, install deps, copy the plugin in, build
./scripts/setup.sh
# 2. quit Discord completely first — Cmd+Q, or tray icon → Quit
./scripts/install.shThen in Discord:
- Settings → Vencord → Plugins
- Search MediaTab, toggle it on
- Reload Discord with
Ctrl+R/Cmd+R— Vencord's patches only apply on a fresh load
A media icon appears in the channel header. Done.
Nothing to Discord itself. Discord's app.asar is already a two-line shim the
official Vencord installer left behind:
require("<vencord data dir>/dist/patcher.js")| Platform | Vencord data dir |
|---|---|
| macOS | ~/Library/Application Support/Vencord |
| Linux | ~/.config/Vencord (or $XDG_CONFIG_HOME/Vencord) |
| Windows | %APPDATA%\Vencord |
install.sh finds this automatically. Override with VENCORD_DIR=... for an
unusual install such as Vesktop or a flatpak.
So there's nothing to re-patch. The script simply makes that dist folder a
symlink to this checkout's build output:
- Discord's app bundle is never touched
- The stock prebuilt Vencord is moved aside to
dist-stock-<timestamp>, not deleted - Your settings are copied to a timestamped backup first
- Rebuilds go live immediately —
./scripts/build.shthenCmd+R, no reinstall
It also turns off Vencord's auto-updater, because that updater replaces dist/
with a downloaded release, which would wipe out this build. Update with
./scripts/update.sh instead — see Updating.
On Windows without Developer Mode, symlinks aren't available and the script
falls back to copying the build into place. Everything works the same, with
one difference: rebuilds are not automatically live, so re-run install.sh
after each build. The script tells you which of the two happened.
This sidesteps Vencord's
pnpm injectentirely, which is an interactive terminal UI that has to be driven by hand. If you ever do need it, runcd Vencord && pnpm injectyourself in a terminal.
Click the media icon in any channel or DM header.
- Start typing in Search message text to narrow by message content.
- Pick people in the author box to see only their media. Selecting nobody means everyone.
- Use the per row dropdown to switch between 2 and 10 columns.
- Hit More ▼ for date range, extension, pinned-only and the tile size slider.
- In a server channel, switch This channel to Whole server to search every channel you can read.
- Switch to the Details layout for a spreadsheet-style view with sortable columns.
Scrolling to the bottom loads more automatically. The subtitle shows how many items are loaded and roughly how many matches exist in total.
Found under Settings → Vencord → Plugins → MediaTab.
| Setting | Default | Notes |
|---|---|---|
| Show the Media button in the channel header | on | Needs a reload to change — it's a patch |
| Also show a Media button next to the message box | off | Applies immediately |
| Which tab the browser opens on | Images | |
| Default layout | Grid | |
| How many items per row in grid view | 4 per row | Also changeable live in the toolbar |
| Tile size | 140px | Only used by "Fit to width"; live slider under More ▼ |
| Blur media that was sent as a spoiler | on | Hovering reveals it |
Run the same one-line command you installed with. That's the whole answer for normal use:
Windows:
powershell -c "irm https://raw.githubusercontent.com/destination/mediatab/main/get.ps1 | iex"
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/destination/mediatab/main/get.sh | bashIt notices the existing install, pulls the latest MediaTab and the latest
Vencord, rebuilds, and relinks. It closes Discord itself for the last step, so
you don't have to quit it first. Your Vencord settings and plugin settings are
untouched — re-runs don't reset anything and don't re-backup anything. Reopen
Discord and press Ctrl+R / Cmd+R when it finishes.
Do this every few weeks. Not because it breaks loudly, but because running a stale client mod is the more realistic risk: patches drift out of date against Discord's code, and a broken patch throws errors inside Discord's own code.
Vencord's built-in auto-updater is deliberately switched off (it would replace this build with a stock download and MediaTab would disappear), so this is the only thing keeping you current.
cd mediatab
./scripts/update.shSame job, plus two extra checks the one-liner skips: it typechecks, and it re-checks the plugin's patch against Discord's current code. If it reports failing tests, the header button probably won't appear — that's the patch needing a nudge, and docs/MAINTENANCE.md walks through fixing it.
Because the build is symlinked, it's live the moment update.sh finishes — just
reload Discord. (If install.sh had to copy rather than symlink — Windows
without Developer Mode — run ./scripts/install.sh again afterwards. update.sh
detects this and says so.)
After changing anything in plugin/mediaTab/:
./scripts/build.sh # sync + build, then Cmd+R in DiscordNo reinstall needed — the dist symlink means a new build is live the moment it
finishes. Or leave a watcher running:
./scripts/watch.sh # rebuilds on save; still press Cmd+R to reloadLet it update normally. Two things worth knowing:
- Your Vencord
distlink lives in the Vencord data folder, which Discord updates don't touch. It survives. - A Discord update can replace
app.asarand remove the Vencord hook, so Discord starts vanilla. If that happens, run the official Vencord installer once to re-create the hook — it points back at the samedistpath, which is still your link, so this plugin comes back with it.
node tests/run.mjs# quit Discord first
./scripts/uninstall.shThat swaps the dist symlink back for the stock Vencord build it moved aside,
so you're exactly where you started. Discord itself was never modified by these
scripts, so there's nothing else to undo. Re-enable auto-update in
Settings → Vencord afterwards if you want it back.
The header button isn't there.
- Is the plugin enabled in Settings → Vencord → Plugins?
- Did you reload with
Cmd+Rafter enabling it? Patches need a fresh load. - Open DevTools (
Cmd+Opt+I) → Console and look for[Vencord] Patch by MediaTab (…) erroredor a "found no module" warning. That means a Discord update moved the code the patch targets — see docs/MAINTENANCE.md, which walks through fixing it. - As a workaround that never depends on patching, right-click the channel in the sidebar and pick View Media, or enable the chat bar button in settings.
"You don't have permission to search here." Discord's search needs Read Message History in that channel. Nothing to fix.
"Discord is rate limiting the search." Searching is rate limited per account. The plugin paces itself to one request at a time and backs off using the delay Discord returns, so this should be rare. Narrower filters mean fewer requests.
The All tab is slower than the others. By design. It searches five media types, and requests go out one at a time rather than all at once — see docs/RULES-AND-RISK.md. The single-type tabs are one request per page and feel instant.
Results are empty in a big server. Discord builds a search index per guild and returns HTTP 202 while that's still happening. The plugin waits and retries automatically, but the first search in a very large server can take a moment.
Videos show a grey tile instead of a thumbnail.
Thumbnails come from media.discordapp.net, which can't produce a still frame
for every codec. The tile still opens and plays normally.
Discord updated and everything broke.
./scripts/setup.sh to rebuild against the latest Vencord. If only the header
button is gone, it's the patch — see docs/MAINTENANCE.md.
.
├── plugin/mediaTab/ the plugin itself — this is the source of truth
│ ├── index.tsx plugin definition, the header patch, entry points
│ ├── headerPatch.ts the patch regex, isolated so tests can verify it
│ ├── MediaBrowser.tsx the modal: toolbar, grid/list/table, actions
│ ├── search.ts Discord search API client + media extraction
│ ├── settings.ts the settings schema
│ ├── types.ts shared types and enums
│ ├── styles.css all styling, themed with Discord's CSS variables
│ └── README.md shown on the plugin's Vencord page
│
├── scripts/
│ ├── setup.sh clone Vencord, install, sync, build
│ ├── sync.sh copy plugin/ into the Vencord checkout
│ ├── build.sh sync + build
│ ├── watch.sh rebuild on save
│ ├── install.sh link Vencord's dist/ at this build
│ ├── update.sh update Vencord, verify the patch, rebuild
│ ├── uninstall.sh put the stock build back
│ └── lib.sh finds Vencord on macOS / Windows / Linux
│
├── tests/
│ ├── run.mjs bundles the plugin with stubs, runs node:test
│ ├── search.test.mjs 34 tests: extraction, queries, pagination
│ ├── patch.test.mjs 5 tests: the patch vs. a real Discord bundle
│ ├── fetch-discord-bundle.mjs downloads Discord's bundle for those tests
│ └── stubs/ fake @webpack/common and @utils/Logger
│
├── docs/ see below
└── Vencord/ the clone (gitignored, disposable)
plugin/mediaTab/ is copied into Vencord/src/userplugins/mediaTab/ by
sync.sh rather than symlinked. A symlink does not work: esbuild resolves the
real path, which lands outside the Vencord checkout, and Vencord's @utils/…
tsconfig path aliases then stop applying.
| Document | What's in it |
|---|---|
| docs/SHARING.md | Giving it to a friend — what they need, what to send, what to warn them about |
| docs/RULES-AND-RISK.md | ToS, ban risk, what "undetectable" can and can't mean, and how the plugin keeps its traffic boring |
| docs/ARCHITECTURE.md | How the plugin is put together, and why |
| docs/DISCORD-SEARCH-API.md | The search endpoint, every parameter, verified against Discord's own client code |
| docs/VENCORD-PLUGINS.md | How Vencord plugins and patches work, as a reference for writing more |
| docs/TESTING.md | What's tested, how the harness works, how to add tests |
| docs/MAINTENANCE.md | Fixing the patch when a Discord update breaks it |
| docs/RESEARCH.md | How the unknowns were pinned down, including the bundle-spelunking method |
GPL-3.0-or-later, matching Vencord.