I Built a 100% Free AI Toolbox with No Sign-Up (Here's How) A developer built MagicKit, a free open-source AI toolbox combining image generation, AI writing, and video creation in a single page with no sign-up, API key, or paywall required. The Node.js/Express backend uses the Pollinations free API for images and FFmpeg for video, running in roughly 60 MB of RAM on a 1.6 GB VPS. The developer worked around the image API's one-request-per-IP queue limit with a retry gate and replaced Node's https module with a curl child process to avoid dropped connections. 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.