↑ ↓ navigate↵ selectesc close
✏️ Blog PostFirebaseCloudflareAI & MCP Agents

Hybrid Web AI Architecture: Routing Between Browser Gemini Nano, Firebase AI Logic, and Edge Workers

Alex Patterson and AJ the Cat illustrating Hybrid Web AI routing between local Chrome Gemini Nano and Edge Cloud AI
✏️ Visual Architecture Diagram

how this post connects together.

Follow AJ from first principles to production-ready architecture.

✏️ Visual Diagram: Hybrid Web AI Architecture: Routing Between Brow…
✓ Good PatternVISUAL DIAGRAM
Visual Diagram: Hybrid Web AI Architecture: Routing Between Brow…Visual architectural diagram showing: Step 1: Hybrid Web AI Architec (Mental model & why it matters) -> Step 2: Hands-On Implementation (Under the hood & live code) -> Step 3: Ship It Purrfectly (✓ Production trade-offs). Step-by-step diagram breakdown for Hybrid Web AI Architecture: Routing Between Browser Gemini Nano, Firebase AI Logic, and Edge Workers: start with Hybrid Web AI Architec, implement Hands-On Implementation, and ship to production.✓Step 01Hybrid Web AI ArchitecMental model & why it matters✓Step 02Hands-On ImplementationUnder the hood & live code✓Step 03Ship It Purrfectly✓ Production trade-offsunroll the yarn✓ production ready
[Diagram Walkthrough]Step-by-step diagram breakdown for Hybrid Web AI Architecture: Routing Between Browser Gemini Nano, Firebase AI Logic, and Edge Workers: start with Hybrid Web AI Architec, implement Hands-On Implementation, and ship to production.
AAA Contrast Verified

The biggest mistake web engineering teams make when adopting client-side AI is treating it as an all-or-nothing binary choice: either 100% of inference runs in the browser or 100% runs in the cloud. In real-world production, visitor hardware spans everything from an M4 Max MacBook Pro with Chrome's on-device Gemini Nano cached in VRAM to a budget mobile browser on a cellular connection. The solution is Hybrid Browser-to-Edge AI Routing.

By pairing Chrome's local window.LanguageModel API with Firebase AI Logic (or a Cloudflare Worker edge gateway calling Gemini 2.5 Flash), you can build a unified TypeScript router that offloads 70%+ of routine summarization, classification, and UI drafting tasks to the user's device at $0 cost while seamlessly routing complex reasoning or unsupported browsers to the edge.

The Mental Model: Adaptive Capability & Complexity Routing

Our hybrid router evaluates three deterministic gates before dispatching a prompt: (1) Hardware Availability (is Chrome's LanguageModel.availability() === 'available' immediately ready without blocking on a multi-hundred-megabyte download?), (2) Context Budget (does the prompt fit comfortably inside Gemini Nano's local token quota?), and (3) Task Complexity (does the request require multi-hop tool calling or massive 100K-token context?).

Dark-mode Architecture Diagram comparing naive single-tier cloud routing against a Hybrid Browser-to-Edge AI Router using Chrome Gemini Nano and Firebase AI Logic
Architecture Diagram: Naive Cloud-Only Routing (left, Coral anti-pattern) vs. Hybrid Browser-to-Edge AI Router combining Local Gemini Nano and Firebase AI Logic / Cloudflare Workers (right, Mint recommended pattern).

Comparing Local-Only, Cloud-Only, and Hybrid Browser-to-Edge Architectures

Architectural MetricLocal-Only (Browser AI)Cloud-Only (Server LLM API)Hybrid Browser-to-Edge Router (Recommended)
Browser CoverageDesktop Chrome / Edge with GPU/NPU100% of browsers (requires network)100% of browsers (local fast-lane + cloud fallback)
P50 Time-to-First-Token (TTFT)15ms to 45ms (0ms network RTT)280ms to 650ms25ms on capable desktops / 280ms on mobile fallback
Unit Economics (50K MAU)$0.00 / month$450 to $1,800 / month70% to 80% cost reduction via local offload
Offline ResilienceFull offline executionFails when offlineGraceful offline mode for local tasks + cloud sync when online

Production Implementation: The Unified Hybrid Web AI Router

Here is the complete TypeScript router pattern that pairs Chrome's native window.LanguageModel with Firebase AI Logic's hybrid on-device/cloud model abstraction and an Astro Cloudflare Worker fallback:

// src/lib/ai/hybrid-web-ai-router.ts
export type InferenceRoute = "local-gemini-nano" | "edge-gemini-flash";

export interface HybridPromptRequest {
  prompt: string;
  systemPrompt?: string;
  complexity?: "fast-local-preferred" | "reasoning-cloud-required";
  maxLocalTokens?: number;
  signal?: AbortSignal;
}

export interface HybridPromptResponse {
  text: string;
  route: InferenceRoute;
  latencyMs: number;
  estimatedCloudCostSavedUsd: number;
}

export async function runHybridWebAiPrompt(
  req: HybridPromptRequest
): Promise<HybridPromptResponse> {
  const start = performance.now();
  const maxLocalTokens = req.maxLocalTokens ?? 2048;

  // 1. Attempt Fast Lane: Local Chrome Built-in AI (Gemini Nano)
  if (req.complexity !== "reasoning-cloud-required") {
    const lm = (globalThis as Record<string, any>).LanguageModel;
    if (lm && typeof lm.availability === "function") {
      try {
        const status = await lm.availability();
        // Only route locally if weights are already warm/available on disk
        if (status === "available") {
          const session = await lm.create({
            systemPrompt:
              req.systemPrompt ??
              "You are a technical assistant on CodingCat.dev. Be concise and accurate.",
            signal: req.signal,
          });
          try {
            const usage = await session.measureInputUsage(req.prompt);
            if (usage <= maxLocalTokens && usage < session.inputQuota - session.inputUsage) {
              const text = await session.prompt(req.prompt, { signal: req.signal });
              return {
                text,
                route: "local-gemini-nano",
                latencyMs: Number((performance.now() - start).toFixed(1)),
                estimatedCloudCostSavedUsd: 0.00042,
              };
            }
          } finally {
            session.destroy();
          }
        }
      } catch (localErr) {
        console.warn("[HybridWebAI] Local Gemini Nano failed, falling back to edge:", localErr);
      }
    }
  }

  // 2. Fallback Lane: Cloudflare Worker / Firebase AI Logic Edge Endpoint (Gemini 2.5 Flash)
  const edgeRes = await fetch("/api/ai/hybrid-fallback", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      prompt: req.prompt,
      systemPrompt: req.systemPrompt,
    }),
    signal: req.signal,
  });

  if (!edgeRes.ok) {
    throw new Error(`Hybrid Edge AI fallback failed with HTTP ${edgeRes.status}`);
  }

  const data = (await edgeRes.json()) as { text: string };
  return {
    text: data.text,
    route: "edge-gemini-flash",
    latencyMs: Number((performance.now() - start).toFixed(1)),
    estimatedCloudCostSavedUsd: 0,
  };
}

Warming the Local Model in the Background Without Blocking UX

Notice how our router above only takes the local fast lane when status === 'available'. What if the user's browser returns 'downloadable'? Instead of making the user wait 30 seconds on their first prompt, fulfill their immediate request via the edge-gemini-flash route while triggering LanguageModel.create() asynchronously in the background. Once the download completes, every subsequent prompt in their session automatically upgrades to the 0ms local lane.

Try the Live Browser AI & WebMCP Playground

You can test every pattern from this article live right now in our interactive Web AI & WebMCP Playground on CodingCat.dev, or inspect our production discovery manifests on the Developers & Agent APIs page. If you are organizing a developer conference or engineering summit, check out my Web AI talk abstracts on alexpatterson.dev and explore more hands-on Courses, Podcasts, and Blog Posts right here on CodingCat.dev.