GIF Deck — a GIF website with a Discord bot

2026-08visit
Next.jsDiscordTypeScript

Share

GIF Deck — a GIF website with a Discord bot

GIF Deck is a top.gg-style GIF site built with Next.js, Tailwind CSS, and MagicUI — with a companion Discord bot bolted on. You search GIFs (your own library plus Giphy), log in with Discord, click any GIF, and the bot sends it either to your DMs or straight into a server channel.

It started as a tiny slash command MVP and grew into a full site. The bot still handles instant /gif picking without opening the browser.

Architecture

Two processes run during development:

The bot client (bot.js, built on discord.js) caches guilds and channels and exposes sendToChannel() / sendDm(). A small db.js reads and writes your own GIF library stored in data/gifs.json.

How the flow works

The round trip from search to sent GIF looks like this:

  1. Open the site and Log in with Discord.
  2. Search — your own data/gifs.json library ranks first, then Giphy results.
  3. Click a GIF, pick DM me or a server + channel, then Send to Discord.
  4. The bot fires the GIF and the site confirms.

Search: your library first

search.js merges your local library with Giphy. Local hits always win, so the GIFs you care about surface before the firehose.

A look at the app

GGIF search page showing GIF results from your library and GiphyGGIF trending page with popular GIFs

Running it locally

You need a Giphy key and a Discord app. Copy .env.example to .env and fill in GIPHY_API_KEY, DISCORD_TOKEN, CLIENT_ID, CLIENT_SECRET, and a REDIRECT_URI of http://localhost:3000/auth/callback. Enable the Server Members intent and use the OAuth2 scopes identify and guilds.

start backend + bot and frontend
# backend + bot on :3001
npm install
npm start

# frontend on :3000 (new terminal)
cd web
npm install
npm run dev

Open http://localhost:3000. Invite the bot to a server with the applications.commands + bot scopes and the Send Messages permission.

Adding your own GIFs

POST to the backend with your admin key — title, tags, and a URL:

add a GIF to your library
curl -X POST http://localhost:3001/gifs \
  -H "Content-Type: application/json" \
  -H "x-admin-key: $ADMIN_KEY" \
  -d '{"title":"thumbs up","tags":["approve","yes"],"url":"https://example.com/thumbsup.gif"}'

Tech stack

What is next

Post-MVP work: swap the in-memory sessions and data/gifs.json for a real database, add a multipart upload endpoint instead of URL-only GIFs, rate-limit /search and /send, and add per-user recently sent history and collections.