DEV Community

Cover image for 4 Weird Browser Tricks Inside My $0/mo Open-Source AI UI Builder (DOM-to-Game Compiler, .glb 3D & 14k Free Requests/Day)
TimofeUS
TimofeUS

Posted on

4 Weird Browser Tricks Inside My $0/mo Open-Source AI UI Builder (DOM-to-Game Compiler, .glb 3D & 14k Free Requests/Day)

If you build a free browser tool with AI in 2026, you immediately hit three walls:

  1. Inference bills eat you alive the moment traffic spikes.
  2. Small/free models hallucinate broken layouts when asked to edit an existing component.
  3. Hosting user-generated pages turns into an XSS nightmare the second someone prompts <script>fetch(...)</script>.

Over the past week I've been building openconstructor — an MIT-licensed, zero-signup visual UI builder that runs directly in the browser with 320+ plain HTML/CSS components and exports to HTML, React, Vue, Svelte, LÖVE 2D, and Roblox Luau / .rbxmx.

If you dig open-source browser tools (or want to poke through the source), a ⭐ on the repo genuinely helps a ton right now while the project is brand new:

GitHub logo Kuloka / openconstructor

Open-source AI interface builder: drag components onto a canvas, ask an AI to build pages, export HTML.

openconstructor — build interfaces with words and blocks

openconstructor

Build interfaces with words and blocks — an open-source, in-browser AI interface builder.

openconstructor.pw — try it live

Roblox UI builder · AI UI generator · 320+ components · HTML to React / Vue / Svelte · LÖVE 2D UI · Gallery


Drop ready-made components onto one shared canvas, move them around freely, and ask an AI model to build or change anything on the page. When you're done, export a single self-contained HTML file.

Features

  • Component catalog — 320+ components in 13 sections (AI & Chat, Dashboard, Commerce, Auth, Landing…), all plain HTML + CSS. Animated ones play on hover.
  • Free-form canvas — drag, pan, zoom, desktop / laptop / tablet / phone sizes.
  • Background editor — solid, linear, radial and mesh gradients, dot / grid / line / noise patterns, or raw CSS.
  • ⚗ Fusion — right-click an element → fuse with… → click another: the AI…

Here are the 4 most useful engineering tricks that came out of building it on a strict $0/month budget.


1. Surviving Traffic on $0: The 413 + Quota Waterfall (~14,000 Free Requests/Day)

Most indie AI wrappers hardcode a single provider and put up a paywall after 3 prompts. Instead, you can chain free-tier and edge inference endpoints into a stateless fallback waterfall where each failure mode routes to a different architecture:

  • Primary (high taste, huge weights): GPT-OSS 120B / Llama 3.3 70B via Cloudflare Workers AI & Groq for fast layout synthesis.
  • High-volume safety net (~14k req/day): Gemma 3 27B on Gemini's free quota. One quirk with Gemma endpoints: system instructions aren't always accepted as a separate system role, and smaller context gateways throw HTTP 413 on big component trees.

Folding the system rules into the first user turn and cascading on 413 / 429 / 5xx made anonymous free generation reliable without touching a credit card:

const PROVIDERS = [
  { name: "workers-gpt-oss", maxTokens: 8000, supportsSystem: true },
  { name: "gemini-gemma-27b", maxTokens: 8192, supportsSystem: false },
  { name: "groq-llama-70b",   maxTokens: 6000, supportsSystem: true },
];

async function generateWithFallback(systemPrompt, userPrompt) {
  for (const p of PROVIDERS) {
    const messages = p.supportsSystem
      ? [
          { role: "system", content: systemPrompt },
          { role: "user", content: userPrompt },
        ]
      : [
          { role: "user", content: `${systemPrompt}\n\n---\nTask:\n${userPrompt}` },
        ];

    const res = await callProvider(p, messages);
    if (res.ok) return res.text();
    if (![413, 429, 500, 502, 503].includes(res.status)) break;
  }
  throw new Error("All free inference routes exhausted");
}
Enter fullscreen mode Exit fullscreen mode

And if a user brings their own API key (OpenRouter, Gemini, Groq, Anthropic, OpenAI, DeepSeek, Cerebras), the key stays in localStorage and talks directly from their browser to the provider — zero backend middleman.


2. Reading getComputedStyle to Compile HTML/CSS Into Game Engines (Lua / Luau)

Web developers aren't the only people who hate hand-coding UI coordinates. Building a shop menu or HUD in Roblox Studio (UDim2, UICorner, UIGradient, UIListLayout) or LÖVE 2D is notoriously tedious compared to Flexbox and CSS Grid.

Instead of writing a fragile CSS parser from scratch, we let the browser's own layout engine do the hard math first:

  1. Mount the component inside a hidden/sandboxed container at the target viewport (1920×1080, phone safe-zone, etc.).
  2. Walk the live DOM tree with getBoundingClientRect() and getComputedStyle(el).
  3. Emit native engine primitives (Frame, TextButton, UICorner, UIStroke in a .rbxmx XML model or Luau LocalScript, or draw calls in LÖVE 2D Lua).
function domNodeToEngineRect(el, rootRect) {
  const rect = el.getBoundingClientRect();
  const cs = getComputedStyle(el);

  return {
    xScale: (rect.left - rootRect.left) / rootRect.width,
    yScale: (rect.top - rootRect.top) / rootRect.height,
    wScale: rect.width / rootRect.width,
    hScale: rect.height / rootRect.height,
    bgColor: cs.backgroundColor,
    radiusPx: parseFloat(cs.borderTopLeftRadius) || 0,
    text: el.childElementCount === 0 ? el.textContent.trim() : null,
  };
}
Enter fullscreen mode Exit fullscreen mode

Because Flexbox, Grid, clamp(), and padding are already resolved by the browser before export, complex responsive cards translate cleanly into engines that have never heard of CSS — and Live Sync mode preserves existing click-handler scripts attached to named buttons.


3. "Component Fusion" & JSON-to-.glb 3D Scenes (Keeping Taste Out of the Prompt)

When you ask a small or mid-sized model to "redesign this pricing table" from scratch, you get style drift: fonts change, spacing collapses, and half the page turns into generic purple gradients.

Three constraints fixed this almost completely:

  • Edit patches instead of full rewrites: When modifying an element on the canvas, the prompt locks the existing visual tokens (palette, border radius, typography) and asks only for the requested delta.
  • ⚗ Component Fusion (Structure A × Style B): Right-click any component on the canvas → Fuse with… → click a second component. Passing the DOM skeleton of A alongside the computed CSS tokens of B gives the model concrete anchors instead of an open-ended prompt.
  • Data-first 3D (.glb export): Asking an LLM to write raw Three.js mesh code fails ~40% of the time. Asking it to emit a declarative JSON scene graph (primitives, PBR materials, lights, keyframe loops) succeeds almost every time — and a lightweight Three.js builder renders it live on the canvas and exports a standard .glb file for Blender, Godot, Unity, or Roblox.

4. Zero-JS Sandboxed Publishing (script-src 'none')

Allowing anonymous users to generate and publish live pages (openconstructor.pw/p/...) usually requires heavy sanitization or isolated subdomains.

We went a simpler route: published pages execute zero JavaScript.

  • Every preview tile in the editor runs inside <iframe sandbox> with scripts and network requests disabled.
  • Published pages ship with strict CSP script-src 'none'.
  • Interactive states (hover reveals, accordions via <details>, multi-screen #anchor prototypes, marquee loops, @keyframes entrances) are 100% pure HTML + CSS.

No XSS vectors, no crypto-miners, instant loads, and zero runtime bundle overhead.


Try It / Break It

You can test the canvas right in the browser with no account and no API key at openconstructor.pw, or run it locally in 3 commands:

git clone https://github.com/Kuloka/openconstructor.git
cd openconstructor
npm install && npm run dev
Enter fullscreen mode Exit fullscreen mode

Question for folks building with LLMs on the frontend: When you generate UIs, do you let the model stream raw HTML/JSX directly, or do you lock it behind a typed JSON schema / component registry? Curious where you drew the line between flexibility and reliability.

Top comments (0)