Blog/Projects/lmaafy

lmaafy — Let Me Ask AI For You

The LMGTFY of the AI age. Generate a link that plays a satisfying typing animation, then redirects to an AI chatbot with your prompt pre-filled. Petty? Maybe. Satisfying? Absolutely.

5/20/2026
4 min read

This content has been generated by GLM 5.1 AI model

Remember LMGTFY? That beautiful, passive-aggressive little tool where you'd send someone a link that would type their question into Google for them? Yeah, those were simpler times.

Well, someone asked me a question the other day that ChatGPT could've answered in 3 seconds flat, and I felt that old familiar urge... but typing "just ask ChatGPT" felt... incomplete. Lacking in dramatic flair.

So I did what any reasonable developer would do: I spent way more time than necessary building a tool to be petty on their behalf.

Enter lmaafy — Let Me Ask AI For You.

How it works

The concept is dead simple:

  1. Type your prompt and pick an AI provider
  2. Hit generate and copy the link
  3. Send it to whoever deserves it

When they open the link, they see a fake cursor smoothly glide across the screen, click into a chat input, and type the prompt character by character with randomized timing (because we're not savages — the typing needs to feel human). Then the cursor clicks send and BAM — redirected to the actual AI provider with the prompt pre-filled and ready to go.

Is it petty? Yes. Is it satisfying? Oh, absolutely.

The tech

Built with TanStack Start (React 19 + Vite + file-based routing), Tailwind CSS v4, shadcn/ui, and TypeScript in strict mode. Monorepo setup with pnpm workspaces and Turborepo because... well, because I apparently can't do anything small.

Just two routes:

  • / — The home page with the form card
  • /ask?d=<base64> — The animation page that does the whole show

No backend. No database. No accounts. Everything lives in the URL as a base64-encoded JSON blob. The prompt and provider ID get packed into { p: string, provider: string }, encoded, and stuffed into a query param. When someone opens the link, it decodes, validates, and the magic begins.

typescript
export function encodeLinkData(data: LinkData): string {
  const json = JSON.stringify(data);
  const bytes = new TextEncoder().encode(json);
  let binary = "";
  for (let i = 0; i < bytes.length; i++) {
    binary += String.fromCharCode(bytes[i]!);
  }
  return btoa(binary);
}

Yeah, it's base64, not encryption. Anyone could decode it. But that's not the point — the point is the punchline isn't staring them in the face from the URL bar. It's about the reveal ^^

The animation engine

This was the fun part. The animation runs through a state machine with phases:

init → move-to-input → click-input → typing → move-to-send → click-send → redirect

The cursor is an SVG arrow that moves using CSS transitions with cubic-bezier(0.16, 1, 0.3, 1) for that satisfying ease-out feel. The typing effect uses randomized delays between 30-80ms per character:

typescript
const delay = Math.random() * 50 + 30;
setTimeout(tick, delay);

The fake chat UI is a generic dark-themed interface — not provider-specific — with a chat input bar at the bottom, a send button, and a blinking cursor during typing. The whole animation takes 3-6 seconds depending on prompt length. Just long enough to be satisfying, short enough to not be annoying.

Supported providers

Only providers that support URL-based prompt pre-filling made the cut:

| Provider | URL Pattern | Notes | |----------|-------------|-------| | ChatGPT | chatgpt.com/?q= | Works like a charm | | Claude | claude.ai/new?q= | Shows a warning banner (not our fault!) | | Grok | grok.com/?q= | Pre-fills nicely | | Mistral LeChat | chat.mistral.ai/chat?q= | Smooth | | T3.chat | t3.chat/new?q= | Needs verification |

Kimi and DeepSeek don't support URL pre-filling, so they didn't make the cut. No point in a dramatic reveal that ends with... nothing.

The "why"

Look, I know this is silly. It's a joke tool. But it's also a surprisingly clean exercise in client-side architecture — no backend, everything in the URL, smooth animations, proper TypeScript types, and it actually works.

Plus, let's be honest: if you're not building at least one passive-aggressive tool per year, are you even a developer?

Try it

Head over to lmaafy.app to try it right now, or clone the GitHub repo, run pnpm install && pnpm dev, and start generating links that passive-aggressively answer questions for you. Your friends will love it. Or hate it. Probably both.

The best part? The whole thing is 100% client-side. No tracking, no cookies, no server. Just pure, unfiltered pettiness delivered directly through a URL.

Use it wisely. Or don't. I'm not your boss.

{{% goodbye %}}