A tiny single-page app: click the button, get a new random meme. No build step, no dependencies, no backend — just static HTML/CSS/JS.
Live: https://leeaky.github.io/meme-button-app/
- One button, one job: fetches a fresh random meme on every click.
- Shows the meme image, its title, and a subreddit/author credit line.
- Loading and error states, so a slow or failed request doesn't look broken.
- Light/dark styling that follows your system theme.
- Loads an initial meme automatically on page load.
- A discreet
xxx/bbcounter in the bottom-right corner: how many memes shown from the current batch, and which batch number it is.
Clone the repo, then serve it:
git clone https://github.com/leeaky/meme-button-app.git
cd meme-button-app
python3 -m http.server 8000Then visit http://localhost:8000. script.js is loaded as an ES module, so
it needs to come from an actual http:// origin — opening index.html
directly via file:// will fail in most browsers (module scripts are
blocked by CORS on the file:// protocol).
-
index.html— page structure: a button, an image, a title, and a credit line. -
style.css— layout and theming (light/dark viaprefers-color-scheme). -
meme-dedupe.js— pure, DOM-free pool/dedup logic (see below), imported byscript.jsand covered by the tests intests/. -
script.js— pulls memes from the public meme-api.com API and serves them one at a time from a local pool:- On first click (and whenever the pool runs out), it fetches a batch of
up to 50 memes from each of 54 subreddits in parallel — general, wholesome,
relatable, anime, programmer/tech, games, movie/TV, history, sports,
and absurdist/low-effort humor — via meme-api.com's documented
GET /gimme/{subreddit}/{count}endpoint (50 is its max per request) — up to ~2700 memes total. Each request is individually capped at 10s (fetchhas no built-in timeout), so one slow/hanging subreddit can't stall the whole refill. - The batches are combined and deduped (dropping anything that's the same post, or has the same title, as something already in the batch or already shown this session), then shuffled once.
- Each click serves the next meme from that shuffled pool, in sequence — rather than asking the API for one random meme per click, which risks landing on something already shown. A batch of ~2700 only needs refilling roughly every 2700 clicks.
- On refill, subreddit "hot" listings don't change every request, so fetching again soon after exhausting a batch can mostly return the same posts. If deduping against session history would leave fewer than 20 memes, that's treated as "the content hasn't refreshed yet" rather than something to retry into oblivion — the new batch is deduped only against itself instead, accepting repeats of older history rather than collapsing down to a batch of 1.
- If every subreddit fetch fails outright, it falls back to the API's own
default
/gimme(single random meme, no dedup) as a last resort.
Either way, a meme object looks like:
{ "title": "...", "url": "https://i.redd.it/...", "subreddit": "memes", "author": "..." }The app renders
urlas the image,titleas the caption, andsubreddit/authoras the credit line. While a request is in flight the button is disabled and shows "Loading...". If everything fails, an error message is shown instead and the button re-enables so you can retry. Open the browser console to see how many memes actually landed in each batch (Loaded a fresh batch of N memes across 54 subreddits) - or just glance at the bottom-right corner, which shows the same thing live asxxx/bb(memes shown from the current batch / batch number). - On first click (and whenever the pool runs out), it fetches a batch of
up to 50 memes from each of 54 subreddits in parallel — general, wholesome,
relatable, anime, programmer/tech, games, movie/TV, history, sports,
and absurdist/low-effort humor — via meme-api.com's documented
The pool/dedup logic (meme-dedupe.js) is covered by tests using Node's
built-in test runner — no dependencies to install:
npm testThis checks title/id matching; deduping across subreddit batches and
against what's already been shown; that the shuffle is a correct,
non-mutating permutation; the xxx/bb counter's formatting; and the
batch-refill fallback that avoids collapsing to a single meme when the
subreddits haven't refreshed since the last batch.
This is a static site, so any static host works (GitHub Pages, Netlify, Vercel, etc.) — just point it at the repo root, no build command needed.
GitHub Pages: requires the repository to be public (or a paid GitHub
plan for private repos). Once public, enable Pages under
Settings → Pages → Source, or use the included
.github/workflows/deploy-pages.yml workflow, which deploys automatically
on every push to main.
- Memes are pulled live from meme-api.com, which in turn sources from public subreddits — content is not curated or filtered, so expect the usual variety (and occasional NSFW-adjacent posts) that come with random Reddit memes.
- No API key, sign-up, or configuration required.