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

> Source: <https://dev.to/magickit/i-built-a-100-free-ai-toolbox-with-no-sign-up-heres-how-1m2b>
> Published: 2026-09-21 00:02:33+00:00

**TL;DR**: I built [MagicKit](http://47.80.8.174) — 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](https://github.com/kaketiti/magickit).

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:

| 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 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:

``` js
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');
}
```

`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"
```

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

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
```

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

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.

🔗 **Live demo**: [http://47.80.8.174](http://47.80.8.174)

💻 **Source**: [https://github.com/kaketiti/magickit](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
```

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

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