DEV Community

kaketiti
kaketiti

Posted on

I Built a 100% Free AI Toolbox with No Sign-Up (Here's How)

TL;DR: I built MagicKit — a free AI toolbox for image generation, AI writing, and video making. No sign-up, no API key, no paywall. The whole thing is open source on GitHub.

Why I built this

Every AI tool these days wants you to sign up, hand over an API key, or subscribe before you can even try it. I wanted the opposite: open the page and just create.

So I spent a few evenings building MagicKit — three tools in one page:

  • 🖼️ AI Image Generator — text-to-image with the FLUX model, multiple aspect ratios
  • ✍️ AI Writer — scripts, copywriting, naming, translation
  • 🎬 AI Video Maker — combine generated images into a short video

The stack (boring on purpose)

Layer Choice Why
Backend Node.js + Express One file, easy to deploy
Frontend Pure HTML/CSS/JS No build step, no framework bloat
AI Pollinations free API No key required
Video FFmpeg Battle-tested, runs on a tiny VPS

The entire backend sits at around 60 MB RAM, because my server only has 1.6 GB to work with.

The hard parts

1. Aggressive rate limits

The free image API only allows one queued request per IP. Concurrent requests instantly return 429 Queue full. My first naive implementation fell over immediately.

The fix:

  • A fully serial queue (concurrency = 1)
  • A global minimum 3-second interval between requests
  • Retry with exponential-ish backoff (up to 5 attempts), detecting 429 responses that come back as tiny error pages instead of real JPEGs
async function generateImageWithRetry(prompt, width, height) {
  for (let attempt = 0; attempt < 5; attempt++) {
    await globalRateLimitGate();        // 3s minimum spacing
    const file = await downloadWithCurl(buildUrl(prompt, width, height));
    if (!isRateLimitError(file)) return file;
    await sleep(3000 * (attempt + 1)); // 3s, 6s, 9s...
  }
  throw new Error('Image service busy, please try again');
}
Enter fullscreen mode Exit fullscreen mode

2. socket hang up from the HTTP client

Node's https module kept dropping connections to the image endpoint under slow responses. I replaced it with a curl child process:

curl -L --max-redirs 5 --max-time 120 --connect-timeout 10 -o output.jpg "$URL"
Enter fullscreen mode Exit fullscreen mode

Boring, predictable, and it never hangs half-open.

3. FFmpeg can silently corrupt output

My first video pipeline used zoompan + xfade filters together. On a 2-core box with 1.6 GB RAM, long runs produced truncated, unplayable MP4s.

The reliable version uses the concat demuxer and a single simple filter for scaling/padding:

ffmpeg -f concat -safe 0 -i list.txt \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,\
pad=1080:1920:(ow-iw)/2:(oh-ih)/2,format=yuv420p" \
  -c:v libx264 out.mp4
Enter fullscreen mode Exit fullscreen mode

No fancy transitions, but the file always plays. Lesson: on constrained hardware, finish reliably beats fancy.

4. Memory discipline

1.6 GB RAM means nothing can be buffered in memory. Generated images go straight to disk, videos stream through FFmpeg, and the queue keeps at most one job in flight.

Try it / run it yourself

🔗 Live demo: http://47.80.8.174
💻 Source: https://github.com/kaketiti/magickit

Self-hosting takes about a minute:

git clone https://github.com/kaketiti/magickit.git
cd magickit
npm install
npm start
Enter fullscreen mode Exit fullscreen mode

It's MIT licensed — fork it, remix it, deploy your own.

Honest limitations

  • The free image API gets slow during peak hours — that's what the retry queue is for
  • Text generation has daily free-tier limits, and the UI tells you plainly when they're exhausted
  • Video synthesis takes a few minutes for longer clips

What's next

  • Pluggable image backends (so when one free provider is throttled, another takes over)
  • Optional self-supplied API keys for power users
  • More aspect-ratio presets and a simple gallery

Feedback is genuinely welcome — what would you add first? Drop a comment or open an issue on GitHub.

Top comments (0)