Skip to content

WilleGyr/TextaGIF

Repository files navigation

TextaGIF

Search GIFs · Caption with Impact · Download the result.
A minimalistic, modern, fully client-side GIF captioning studio.

React TypeScript Vite Tailwind CSS

License Platform Runs Font Status PRs

Demo · Quick Start · Features · How It Works · API Keys · Roadmap · License


Demo

Search grid
Search. Unified Giphy + Klipy grid with hover previews and source toggle.
Editor
Caption. Live Impact preview, top/bottom toggle, 1–300px size, one-click render.

Overview

TextaGIF is a tiny, opinionated meme studio. Search Giphy and Klipy, pick a GIF, slap an Impact caption on the top or bottom at any size from 1–300 pixels, and the tool burns the text into every frame and hands you back a fresh .gif.

No uploads. No server. No tracking. The entire render pipeline — decode, composite, re-encode — runs in your browser.

Search

Giphy + Klipy, unified results grid with hover previews.

Caption

Impact font, auto-wrap, white fill + black stroke, live SVG preview.

Download

Per-frame render with gifuct-js + gifenc, 100% client-side.

Features

Multi-source search Giphy and Klipy, toggleable in one click.
Live caption preview SVG overlay scales exactly with the displayed GIF so what you see is what you get.
Top / Bottom positioning Classic meme format, one tap to flip.
Font size 1–300 Slider + numeric input. Use 1 for subtle signatures or 300 for screen-smashers.
Auto word-wrap Captions wrap on word boundaries with padding-aware margins.
Impact, always Bold Impact with black stroke — the true language of memes.
Fully client-side Nothing is uploaded. The generated GIF is assembled in your browser.
Minimalist UI Dark, typographic, no clutter. Sticky search header, keyboard-friendly, mobile-friendly.
Zero tracking No analytics. No cookies. No accounts.

Quick Start

# 1. Install
npm install

# 2. Add API keys
cp .env.example .env.local
# open .env.local and paste at least one key (see below)

# 3. Run it
npm run dev

Open http://localhost:5173 and you're in.


API Keys

You need at least one. Both are free.

Provider Get a key Env var
Giphy

developers.giphy.comCreate an App → pick API (not SDK)

VITE_GIPHY_KEY
Klipy

business.klipy.comCreate API Key

VITE_KLIPY_KEY

Tenor is no longer accepting new API clients as of January 2026, so TextaGIF uses Klipy as its second provider.


How It Works

flowchart LR
  A[Search query] --> B{Source}
  B -->|Giphy| C[Giphy REST API]
  B -->|Klipy| D[Klipy REST API]
  C --> E[Grid of previews]
  D --> E
  E --> F[Select a GIF]
  F --> G[Fetch original bytes]
  G --> H[Decode frames<br/>gifuct-js]
  H --> I[Composite + draw caption<br/>Canvas 2D + Impact]
  I --> J[Quantize + encode<br/>gifenc]
  J --> K[Download .gif]
Loading

The render path (src/lib/gifProcessor.ts):

  1. Fetch the original GIF as an ArrayBuffer.
  2. Parse + decompress each frame with gifuct-js, respecting disposal modes (restore, clear, keep).
  3. Composite the frame patch onto a running canvas.
  4. Overlay the caption — Impact, white fill, proportional black stroke, word-wrapped to frame width.
  5. Quantize frame pixels to a 256-color palette (gifenc quantize) and encode with per-frame delays.
  6. Save via a blob download. Snapshot is restored so subsequent frames don't see baked-in text.

Tech Stack

Frontend

  • React 18
  • TypeScript 5
  • Vite 5
  • Tailwind CSS 3

GIF pipeline

  • gifuct-js — decode
  • gifenc — encode + quantize
  • Canvas 2D — compositing
  • SVG — live preview overlay

Sources


Project Structure

TextaGIF/
├── src/
│   ├── components/
│   │   ├── SearchBar.tsx      # search input + source toggle
│   │   ├── GifGrid.tsx        # results grid + skeleton + empty states
│   │   └── Editor.tsx         # preview + caption controls + download
│   ├── lib/
│   │   ├── api.ts             # Giphy + Klipy clients, typed responses
│   │   └── gifProcessor.ts    # decode → caption → re-encode pipeline
│   ├── App.tsx                # shell, routing between grid and editor
│   ├── main.tsx               # React root
│   ├── types.ts               # shared types (GifItem, CaptionSettings…)
│   └── index.css              # Tailwind + base styles
├── docs/
│   └── banner.svg             # README header
├── index.html
├── tailwind.config.js
├── vite.config.ts
├── tsconfig.json
└── package.json

Scripts

Command What it does
npm run dev Start the Vite dev server on :5173 with HMR.
npm run build Type-check and produce an optimized production build in dist/.
npm run preview Serve the production build locally.

Configuration

Environment variables
Variable Required Purpose
VITE_GIPHY_KEY one-of Giphy REST API key
VITE_KLIPY_KEY one-of Klipy REST API key

At least one must be set. Unconfigured providers are greyed out in the source toggle.

Tweaking caption style

Open src/lib/gifProcessor.ts and edit drawCaption. The defaults:

ctx.fillStyle  = "#ffffff";
ctx.strokeStyle = "#000000";
ctx.lineWidth  = Math.max(2, fontSize / 14);

Swap in a different color, gradient, or shadow. The live preview in Editor.tsx mirrors these values in SVG — update both so what you see matches what you download.

Adding a third source
  1. Extend GifSource in src/types.ts.
  2. Add a searchXxx function in src/lib/api.ts returning GifItem[].
  3. Route it in searchGifs and add an isXxxConfigured export.
  4. Wire the toggle in SearchBar.tsx and the setup banner in App.tsx.

The search surface is tiny on purpose — each provider is ~30 lines.


Roadmap

  • Giphy + Klipy search
  • Impact caption (top / bottom, 1–300px)
  • Live preview
  • Client-side GIF re-encode
  • Multi-line manual breaks
  • Custom fill / stroke colors
  • Drag-to-position caption (freeform)
  • Trim / crop / speed adjust
  • Upload-your-own-GIF source

Got an idea? Open an issue.


Contributing

Pull requests are welcome. For bigger changes, open an issue first to chat about direction.

git clone <your-fork>
cd TextaGIF
npm install
npm run dev

Please keep the UI minimalistic. Fewer buttons. Less chrome. More Impact.


Acknowledgments

  • gifuct-js — the GIF decoder that makes frame-accurate compositing possible.
  • gifenc — a wonderfully small, fast GIF encoder.
  • Giphy and Klipy — for the endless supply of reactions.
  • shields.io — badges above.

License

MIT © TextaGIF contributors.


Built with Impact · Captioned with care.

About

fully client-side meme studio — search Giphy and Klipy, caption with Impact at any size from 1–300px, and download a freshly re-encoded GIF. No uploads, no server.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors