1<!DOCTYPE html><!--NvkFI3K3JcWeGnty8vGQq--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/68d403cf9f2c68c5-s.p.f9f15f61.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/70bc3e132a0a741e-s.p.15008bfb.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/chunks/e78bca1c67f3c6b8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/086b243adc657d55.js"/>
1<script src="/_next/static/chunks/18e416426aee4334.js" async=""></script>
1<script src="/_next/static/chunks/8db8e537a6f2abd2.js" async=""></script>
1<script src="/_next/static/chunks/440b7932303aa943.js" async=""></script>
1<script src="/_next/static/chunks/b48d2d4b029b2afe.js" async=""></script>
1<script src="/_next/static/chunks/turbopack-ecd47d0085b74423.js" async=""></script>
1<script src="/_next/static/chunks/c117910d669fdd7f.js" async=""></script>
1<script src="/_next/static/chunks/d2efd6138645d809.js" async=""></script>
1<script src="/_next/static/chunks/2b1e452b2b1f7f3a.js" async=""></script>
1<script src="/_next/static/chunks/2e6e09be009c86ac.js" async=""></script>
1<script src="/_next/static/chunks/67480a1d5392c377.js" async=""></script>
1<meta name="next-size-adjust" content=""/><meta name="theme-color" media="(prefers-color-scheme: light)" content="white"/><meta name="theme-color" media="(prefers-color-scheme: dark)" content="black"/><title>How It Works | TinyWhale</title><meta name="description" content="Learn how TinyWhale runs AI models on-device across Chrome extensions, browsers, mobile, and desktop using WebGPU, Transformers.js, and llama.cpp."/><meta name="author" content="TinyWhale"/><meta name="keywords" content="in-browser AI,WebGPU,browser AI,transformers.js,open source LLM,local LLM,private AI,ONNX,web inference"/><meta name="creator" content="TinyWhale"/><meta name="robots" content="index, follow"/><meta name="googlebot" content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"/><meta property="og:title" content="TinyWhale - In-Browser AI Chat"/><meta property="og:description" content="Chat with open source LLMs running entirely in your browser via WebGPU. No server, no data leaves your device."/><meta property="og:url" content="https://tinywhale.dev"/><meta property="og:site_name" content="TinyWhale"/><meta property="og:locale" content="en_US"/><meta property="og:image" content="https://tinywhale.dev/og-image.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="TinyWhale - In-Browser AI Chat"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:creator" content="@tantara"/><meta name="twitter:title" content="TinyWhale - In-Browser AI Chat"/><meta name="twitter:description" content="Chat with open source LLMs running entirely in your browser via WebGPU. No server, no data leaves your device."/><meta name="twitter:image" content="https://tinywhale.dev/og-image.png"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/favicon-32.png" sizes="32x32" type="image/png"/><link rel="icon" href="/favicon-16.png" sizes="16x16" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
1<script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script>
1</head><body class="bg-background text-foreground min-h-screen font-sans antialiased inter_dd475d0c-module__9A3jha__variable source_serif_4_81d6187e-module__GRic1G__variable jetbrains_mono_9a7616cc-module__ve5NeG__variable"><div hidden=""><!--$--><!--/$--></div>
1<script>(function(){let a=localStorage.getItem("theme-mode")??"light",b=["light","dark","auto"].includes(a)?a:"light";if("auto"===b){let a=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";document.documentElement.classList.add(a,"auto")}else document.documentElement.classList.add(b)})();</script>
1<div class="flex min-h-screen flex-col bg-ocean-foam text-ocean-text"><nav class="fixed top-0 right-0 left-0 z-50 transition-all duration-200 bg-transparent"><div class="container flex items-center justify-between py-4"><a class="flex items-center gap-2 font-semibold" href="/"><img alt="TinyWhale logo" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" style="color:transparent" src="/logo.svg"/><span class="text-lg">TinyWhale</span></a><div class="hidden items-center gap-6 md:flex"><a class="text-foreground/70 hover:text-foreground text-sm font-medium transition-colors" href="/#features">Features</a><a class="text-foreground/70 hover:text-foreground text-sm font-medium transition-colors" href="/how-it-works">How It Works</a><a class="text-foreground/70 hover:text-foreground text-sm font-medium transition-colors" href="/download">Download</a><a class="text-foreground/70 hover:text-foreground text-sm font-medium transition-colors" href="/chat">Chat</a></div><div class="hidden items-center gap-2 md:flex"><a href="https://github.com/tantara/transformers.js-chrome" target="_blank" rel="noopener noreferrer" aria-label="GitHub" data-slot="button" class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 size-9"><svg viewBox="0 0 24 24" class="size-5" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"></path></svg></a><button data-slot="dropdown-menu-trigger" class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border shadow-xs size-9 [&>svg]:absolute [&>svg]:size-5 [&>svg]:scale-0" type="button" id="radix-_R_2danpfdb_" aria-haspopup="menu" aria-expanded="false" data-state="closed"><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" class="light:scale-100! auto:scale-0!"><path d="M7.5 0C7.77614 0 8 0.223858 8 0.5V2.5C8 2.77614 7.77614 3 7.5 3C7.22386 3 7 2.77614 7 2.5V0.5C7 0.223858 7.22386 0 7.5 0ZM2.1967 2.1967C2.39196 2.00144 2.70854 2.00144 2.90381 2.1967L4.31802 3.61091C4.51328 3.80617 4.51328 4.12276 4.31802 4.31802C4.12276 4.51328 3.80617 4.51328 3.61091 4.31802L2.1967 2.90381C2.00144 2.70854 2.00144 2.39196 2.1967 2.1967ZM0.5 7C0.223858 7 0 7.22386 0 7.5C0 7.77614 0.223858 8 0.5 8H2.5C2.77614 8 3 7.77614 3 7.5C3 7.22386 2.77614 7 2.5 7H0.5ZM2.1967 12.8033C2.00144 12.608 2.00144 12.2915 2.1967 12.0962L3.61091 10.682C3.80617 10.4867 4.12276 10.4867 4.31802 10.682C4.51328 10.8772 4.51328 11.1938 4.31802 11.3891L2.90381 12.8033C2.70854 12.9986 2.39196 12.9986 2.1967 12.8033ZM12.5 7C12.2239 7 12 7.22386 12 7.5C12 7.77614 12.2239 8 12.5 8H14.5C14.7761 8 15 7.77614 15 7.5C15 7.22386 14.7761 7 14.5 7H12.5ZM10.682 4.31802C10.4867 4.12276 10.4867 3.80617 10.682 3.61091L12.0962 2.1967C12.2915 2.00144 12.608 2.00144 12.8033 2.1967C12.9986 2.39196 12.9986 2.70854 12.8033 2.90381L11.3891 4.3
11802C11.1938 4.51328 10.8772 4.51328 10.682 4.31802ZM8 12.5C8 12.2239 7.77614 12 7.5 12C7.22386 12 7 12.2239 7 12.5V14.5C7 14.7761 7.22386 15 7.5 15C7.77614 15 8 14.7761 8 14.5V12.5ZM10.682 10.682C10.8772 10.4867 11.1938 10.4867 11.3891 10.682L12.8033 12.0962C12.9986 12.2915 12.9986 12.608 12.8033 12.8033C12.608 12.9986 12.2915 12.9986 12.0962 12.8033L10.682 11.3891C10.4867 11.1938 10.4867 10.8772 10.682 10.682ZM5.5 7.5C5.5 6.39543 6.39543 5.5 7.5 5.5C8.60457 5.5 9.5 6.39543 9.5 7.5C9.5 8.60457 8.60457 9.5 7.5 9.5C6.39543 9.5 5.5 8.60457 5.5 7.5ZM7.5 4.5C5.84315 4.5 4.5 5.84315 4.5 7.5C4.5 9.15685 5.84315 10.5 7.5 10.5C9.15685 10.5 10.5 9.15685 10.5 7.5C10.5 5.84315 9.15685 4.5 7.5 4.5Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" class="auto:scale-0! dark:scale-100!"><path d="M2.89998 0.499976C2.89998 0.279062 2.72089 0.0999756 2.49998 0.0999756C2.27906 0.0999756 2.09998 0.279062 2.09998 0.499976V1.09998H1.49998C1.27906 1.09998 1.09998 1.27906 1.09998 1.49998C1.09998 1.72089 1.27906 1.89998 1.49998 1.89998H2.09998V2.49998C2.09998 2.72089 2.27906 2.89998 2.49998 2.89998C2.72089 2.89998 2.89998 2.72089 2.89998 2.49998V1.89998H3.49998C3.72089 1.89998 3.89998 1.72089 3.89998 1.49998C3.89998 1.27906 3.72089 1.09998 3.49998 1.09998H2.89998V0.499976ZM5.89998 3.49998C5.89998 3.27906 5.72089 3.09998 5.49998 3.09998C5.27906 3.09998 5.09998 3.27906 5.09998 3.49998V4.09998H4.49998C4.27906 4.09998 4.09998 4.27906 4.09998 4.49998C4.09998 4.72089 4.27906 4.89998 4.49998 4.89998H5.09998V5.49998C5.09998 5.72089 5.27906 5.89998 5.49998 5.89998C5.72089 5.89998 5.89998 5.72089 5.89998 5.49998V4.89998H6.49998C6.72089 4.89998 6.89998 4.72089 6.89998 4.49998C6.89998 4.27906 6.72089 4.09998 6.49998 4.09998H5.89998V3.49998ZM1.89998 6.49998C1.89998 6.27906 1.72089 6.09998 1.49998 6.09998C1.27906 6.09998 1.09998 6.27906 1.09998 6.49998V7.09998H0.499976C0.279062 7.09998 0.0999756 7.27906 0.0999756 7.49998C0.0999756 7.72089 0.279062 7.89998 0.499976 7.89998H1.09998V8.49998C1.09998 8.72089 1.27906 8.89997 1.49998 8.89997C1.72089 8.89997 1.89998 8.72089 1.89998 8.49998V7.89998H2.49998C2.72089 7.89998 2.89998 7.72089 2.89998 7.49998C2.89998 7.27906 2.72089 7.09998 2.49998 7.09998H1.89998V6.49998ZM8.54406 0.98184L8.24618 0.941586C8.03275 0.917676 7.90692 1.1655 8.02936 1.34194C8.17013 1.54479 8.29981 1.75592 8.41754 1.97445C8.91878 2.90485 9.20322 3.96932 9.20322 5.10022C9.20322 8.37201 6.82247 11.0878 3.69887 11.6097C3.45736 11.65 3.20988 11.6772 2.96008 11.6906C2.74563 11.702 2.62729 11.9535 2.77721 12.1072C2.84551 12.1773 2.91535 12.2458 2.98667 12.3128L3.05883 12.3795L3.31883 12.6045L3.50684 12.7532L3.62796 12.8433L3.81491 12.9742L3.99079 13.089C4.11175 13.1651 4.23536 13.2375 4.36157 13.3059L4.62496 13.4412L4.88553 13.5607L5.18837 13.6828L5.43169 13.7686C5.56564 13.8128 5.70149 13.8529 5.83857 13.8885C5.94262 13.9155 6.04767 13.9401 6.15405 13.9622C6.27993 13.9883 6.40713 14.0109 6.53544 14.0298L6.85241 14.0685L7.11934 14.0892C7.24637 14.0965 7.37436 14.1002 7.50322 14.1002C11.1483 14.1002 14.1032 11.1453 14.1032 7.50023C14.1032 7.25044 14.0893 7.00389 14.0623 6.76131L14.0255 6.48407C13.991 6.26083 13.9453 6.04129 13.8891 5.82642C13.8213 5.56709 13.7382 5.31398 13.6409 5.06881L13.5279 4.80132L13.4507 4.63542L13.3766 4.48666C13.2178 4.17773 13.0353 3.88295 12.8312 3.60423L12.6782 3.40352L12.4793 3.16432L12.3157 2.98361L12.1961 2.85951L12.0355 2.70246L11.8134 2.50184L11.4925 2.24191L11.2483 2.06498L10.9562 1.87446L10.6346 1.68894L10.3073 1.52378L10.1938 1.47176L9.95488 1.3706L9.67791 1.2669L9.42566 1.1846L9.10075 1.09489L8.83599 1.03486L8.54406 0.98184ZM10.4032 5.30023C10.4032 4.27588 10.2002 3.29829 9.83244 2.40604C11.7623 3.28995 13.1032 5.23862 13.1032 7.50023C13.1032 10.593 10.596 13.1002 7.50322 13.1002C6.63646 13.1002 5.81597 12.9036 5.08355 12.5522C6.5419 12.0941 7.81081 11.2082 8.74322 10.0416C8.87963 10.2284 9.10028 10.3497 9.34928 10.3497C9.76349 10.3497 10.0993 10.0139 10.0993 9.59971C10.0993 9.24256 9.84965 8.94373 9.51535 8.86816C9.57741 8.75165 9.63653 8.63334 9.6926 8.51332C9.88358 8.63163 10.1088 8.69993 10.35 8.69993C11.0403 8.69993 11.6 8.14028 11.6 7.44993C11.6 6.75976 11.0406 6.20024 10.3505 6.19993C10.3853 5.90487 10.4032 5.60464 10.4032 5.30023Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg><svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" class="auto:scale-100!"><path d="M1 3.25C1 3.11193 1.11193 3 1.25 3H13.75C13.8881 3 14 3.11193 14 3.25V10.75C14 10.8881 13.8881 11 13.75 11H1.25C1.11193 11 1 10.8881 1 10.75V3.25ZM1.25 2C0.559643 2 0 2.55964 0 3.25V10.75C0 11.4404 0.559644 12 1.25 12H5.07341L4.82991 13.2986C4.76645 13.6371 5.02612 13.95 5.37049 13.95H9.62951C9.97389 13.95 10.2336 13.6371 10.1701 13.2986L9.92659 12H13.75C14.4404 12 15 11.4404 15 10.75V3.25C15 2.55964 14.4404 2
113.75 2H1.25ZM9.01091 12H5.98909L5.79222 13.05H9.20778L9.01091 12Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg><span class="sr-only">Toggle theme</span></button></div><button class="text-foreground p-2 md:hidden" aria-label="Toggle menu"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-6"><line x1="4" x2="20" y1="12" y2="12"></line><line x1="4" x2="20" y1="6" y2="6"></line><line x1="4" x2="20" y1="18" y2="18"></line></svg></button></div></nav><main class="flex-1"><section class="px-4 pt-28 pb-12 text-center sm:px-6 sm:pt-32 sm:pb-16"><h1 class="mb-4 text-3xl font-bold tracking-tight text-ocean-text sm:text-4xl md:text-5xl">How It Works</h1><p class="mx-auto max-w-2xl text-base text-ocean-text-muted sm:text-lg">TinyWhale runs LLMs entirely on your device â across Chrome extensions, browsers, mobile apps, and desktop. No servers, no cloud, no data collection.</p></section><section class="px-4 pb-12 sm:px-6 sm:pb-16"><div class="mx-auto grid max-w-4xl gap-6 sm:gap-8 md:grid-cols-3"><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-8"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7,10 12,15 17,10"></polyline><line x1="12" x2="12" y1="15" y2="3"></line></svg></div><div class="mb-1 text-sm font-medium text-ocean-text-muted">Step <!-- -->01</div><h3 class="mb-2 text-lg font-semibold text-ocean-text">Load the Model</h3><p class="text-sm leading-relaxed text-ocean-text-muted">An open source LLM (quantized to 4-bit) is downloaded directly into your browser. The model files are cached locally, so subsequent visits load instantly. The entire model is only ~500MB thanks to 4-bit quantization.</p></div><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-8"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg></div><div class="mb-1 text-sm font-medium text-ocean-text-muted">Step <!-- -->02</div><h3 class="mb-2 text-lg font-semibold text-ocean-text">Chat Privately</h3><p class="text-sm leading-relaxed text-ocean-text-muted">All inference runs locally on your GPU via WebGPU. Your conversations never leave your device â there's no server, no API calls, no telemetry. Once loaded, it even works offline.</p></div><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-8"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"></path><circle cx="12" cy="12" r="3"></circle></svg></div><div class="mb-1 text-sm font-medium text-ocean-text-muted">Step <!-- -->03</div><h3 class="mb-2 text-lg font-semibold text-ocean-text">Customize & Explore</h3><p class="text-sm leading-relaxed text-ocean-text-muted">Fine-tune generation with temperature, top-p, top-k, and more. Upload images for vision tasks â our models support multimodal input. Experiment with different settings to get the best results.</p></div></div></section><section class="bg-ocean-shallow px-4 py-12 sm:px-6 sm:py-16"><div class="mx-auto max-w-5xl"><h2 class="mb-4 text-center text-2xl font-bold text-ocean-text sm:text-3xl">4 Platforms, One Monorepo</h2><p class="mx-auto mb-10 max-w-2xl text-center text-sm text-ocean-text-muted sm:text-base">Same goal â on-device LLM inference â but each platform uses different engines and model formats optimized for its runtime.</p><div class="grid gap-6 md:grid-cols-2"><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 flex items-center gap-3"><div class="text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-6"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15,3 21,3 21,9"></polyline><line x1="10" x2="21" y1="14" y2="3"></line></svg></div><div><h3 class="text-lg font-semibold text-ocean-text">Chrome Extension</h3><span class="inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20">Plasmo MV3</span></div></div><p class="mb-4 text-sm leading-relaxed text-ocean-text-muted">Run LLMs directly in a Chrome side panel. The service worker loads the model and streams tokens to the UI via chrome.runtime.sendMessage().</p><div class="mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30"><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Inference Engine</span><span class="font-medium text-ocean-text">Transformers.js</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Model Format</span><span class="font-medium text-ocean-text">ONNX (q4f16)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">GPU Acceleration</span><span class="font-medium text-ocean-text">WebGPU</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Execution Context</span><span class="font-medium text-ocean-text">Service Worker</span></div><div class="flex items-center justify-between px-3 py-2 text-xs "><span class="text-ocean-text-muted">
1Default Model</span><span class="font-medium text-ocean-text">Qwen3.5-0.8B</span></div></div><ul class="space-y-2"><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Service worker requires build patches: import.meta.url rewriting, Node module stubs (fs, sharp, onnxruntime-node), and env.js patching for IS_BROWSER_ENV</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Auto-detects WebGPU FP16 support (shader-f16) and falls back to q4 quantization when unavailable</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Supports Firefox MV2 (sidebar_action) and Safari (Xcode conversion) from the same codebase</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Models include text generation (Llama, Qwen, Phi, SmolLM, DeepSeek-R1), vision (Qwen VL, Janus), and speech-to-text (Whisper)</li></ul></div><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 flex items-center gap-3"><div class="text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-6"><circle cx="12" cy="12" r="10"></circle><path d="M2 12h20"></path><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg></div><div><h3 class="text-lg font-semibold text-ocean-text">Browser</h3><span class="inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20">Next.js</span></div></div><p class="mb-4 text-sm leading-relaxed text-ocean-text-muted">In-browser AI chat using a Web Worker to keep the main thread responsive. The LLMPipeline singleton loads the model once and handles both text-only and vision (image+text) inference.</p><div class="mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30"><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Inference Engine</span><span class="font-medium text-ocean-text">Transformers.js</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Model Format</span><span class="font-medium text-ocean-text">ONNX (q4f16)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">GPU Acceleration</span><span class="font-medium text-ocean-text">WebGPU (Web Worker)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Execution Context</span><span class="font-medium text-ocean-text">Web Worker</span></div><div class="flex items-center justify-between px-3 py-2 text-xs "><span class="text-ocean-text-muted">Default Model</span><span class="font-medium text-ocean-text">Qwen3.5-0.8B</span></div></div><ul class="space-y-2"><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Uses AutoModelForImageTextToText + AutoProcessor for unified text and vision inference in a single model</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>TextStreamer provides real-time token streaming with TPS (tokens/sec) and TTFT (time to first token) metrics</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>InterruptableStoppingCriteria allows users to stop generation mid-stream</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>No build compatibility hacks needed â Web Workers support standard ES modules natively</li></ul></div><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 flex items-center gap-3"><div class="text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-6"><rect width="14" height="20" x="5" y="2" rx="2" ry="2"></rect><path d="M12 18h.01"></path></svg></div><div><h3 class="text-lg font-semibold text-ocean-text">Mobile</h3><span class="inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20">Expo + llama.rn</span></div></div><p class="mb-4 text-sm leading-relaxed text-ocean-text-muted">Native mobile inference using llama.rn, a React Native binding to llama.cpp via JSI (JavaScript Interface). GGUF models run with Metal GPU acceleration on iOS.</p><div class="mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30"><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Inference Engine</span><span class="font-medium text-ocean-text">llama.cpp (JSI)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Model Format</span><span class="font-medium text-ocean-text">GGUF</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">GPU Acceleration</span><span class="font-medium text-ocean-text">Metal (iOS) / OpenCL (Android)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Execution Context</span><span class="font-medium text-ocean-text">Native Thread</span></div><div class="flex items-center justify-between px-3 py-2 text-xs "><span class="text-ocean-text-muted">Framework</span><span class="font-medium text-ocean-text">Expo SDK 54</span></div></div><ul class="space-y-2"><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>JSI bindings bypass the React Native Bridge for near-native performance â direct
1C++ to JavaScript calls</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>iOS uses Metal with up to 99 GPU layers; Android supports CPU and optional OpenCL GPU offloading</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>All llama.cpp symbols are prefixed with lm_ to prevent namespace conflicts with other native libraries</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Supports multimodal (vision/audio), embeddings, grammar sampling (GBNF/JSON schema), and tool calling</li></ul></div><div class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><div class="mb-4 flex items-center gap-3"><div class="text-ocean-deep"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="size-6"><rect width="20" height="14" x="2" y="3" rx="2"></rect><line x1="8" x2="16" y1="21" y2="21"></line><line x1="12" x2="12" y1="17" y2="21"></line></svg></div><div><h3 class="text-lg font-semibold text-ocean-text">Desktop</h3><span class="inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20">Tauri + Rust</span></div></div><p class="mb-4 text-sm leading-relaxed text-ocean-text-muted">Lightweight desktop app with a Rust backend that calls llama.cpp directly via the llama-cpp-2 crate. Models are auto-downloaded from Hugging Face Hub with real-time progress tracking.</p><div class="mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30"><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Inference Engine</span><span class="font-medium text-ocean-text">llama-cpp-2 (Rust)</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Model Format</span><span class="font-medium text-ocean-text">GGUF</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">GPU Acceleration</span><span class="font-medium text-ocean-text">CPU + optional GPU</span></div><div class="flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10"><span class="text-ocean-text-muted">Execution Context</span><span class="font-medium text-ocean-text">Rust Thread</span></div><div class="flex items-center justify-between px-3 py-2 text-xs "><span class="text-ocean-text-muted">Frontend</span><span class="font-medium text-ocean-text">Vite + React</span></div></div><ul class="space-y-2"><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Tauri uses the system WebView instead of bundling Chromium â dramatically smaller app size vs Electron</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Rust backend manages model lifecycle with Arc<Mutex<ModelStore>> for thread-safe concurrent access</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Hugging Face Hub integration auto-discovers GGUF files and prefers q4_k_m quantization</li><li class="flex gap-2 text-xs leading-relaxed text-ocean-text-muted"><span class="mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60"></span>Download progress events are emitted via Tauri IPC to the React frontend in real-time</li></ul></div></div></div></section><section class="px-4 py-12 sm:px-6 sm:py-16"><div class="mx-auto max-w-5xl"><h2 class="mb-8 text-center text-2xl font-bold text-ocean-text sm:text-3xl">Platform Comparison</h2><div class="overflow-x-auto rounded-xl border border-ocean-mid/20 bg-white/60 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40"><table class="w-full text-sm"><thead><tr class="border-b border-ocean-mid/20"><th class="px-4 py-3 text-left font-medium text-ocean-text-muted"></th><th class="px-4 py-3 text-left font-semibold text-ocean-text">Chrome Extension</th><th class="px-4 py-3 text-left font-semibold text-ocean-text">Browser</th><th class="px-4 py-3 text-left font-semibold text-ocean-text">Mobile</th><th class="px-4 py-3 text-left font-semibold text-ocean-text">Desktop</th></tr></thead><tbody><tr class="border-b border-ocean-mid/10"><td class="px-4 py-3 font-medium text-ocean-text-muted">Inference Engine</td><td class="px-4 py-3 text-ocean-text">Transformers.js</td><td class="px-4 py-3 text-ocean-text">Transformers.js</td><td class="px-4 py-3 text-ocean-text">llama.cpp (JSI)</td><td class="px-4 py-3 text-ocean-text">llama.cpp (Rust)</td></tr><tr class="border-b border-ocean-mid/10"><td class="px-4 py-3 font-medium text-ocean-text-muted">Model Format</td><td class="px-4 py-3 text-ocean-text">ONNX</td><td class="px-4 py-3 text-ocean-text">ONNX</td><td class="px-4 py-3 text-ocean-text">GGUF</td><td class="px-4 py-3 text-ocean-text">GGUF</td></tr><tr class="border-b border-ocean-mid/10"><td class="px-4 py-3 font-medium text-ocean-text-muted">GPU Acceleration</td><td class="px-4 py-3 text-ocean-text">WebGPU</td><td class="px-4 py-3 text-ocean-text">WebGPU</td><td class="px-4 py-3 text-ocean-text">Metal / OpenCL</td><td class="px-4 py-3 text-ocean-text">CPU + GPU</td></tr><tr class="border-b border-ocean-mid/10"><td class="px-4 py-3 font-medium text-ocean-text-muted">Execution Context</td><td class="px-4 py-3 text-ocean-text">Service Worker</td><td class="px-4 py-3 text-ocean-text">Web Worker</td><td class="px-4 py-3 text-ocean-text">Native Thread</td><td class="px-4 py-3 text-ocean-text">Rust Thread</td></tr><tr class=""><td class="px-4 py-3 font-medium text-ocean-text-muted">Installation</td><td class="px-4 py-3 text-ocean-text">Chrome Web Store</td><td class="px-4 py-3 text-ocean-text">None (URL)</td><td class="px-4 py-3 text-ocean-text">App Store</td><td class="px-4 py-3 text-ocean-text">Download</td></tr></tbody></table></div></div></section><section class="bg-ocean-shallow px-4 py-12 sm:px-6 sm:py-16"><div class="mx-auto max-w-5xl"><h2 class="mb-8 text-center text-2xl font-bold text-ocean-text sm:text-3xl">Technology Stack</h2><div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"><a href="https://huggingface.co/docs/transformers.js" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">Transformers.js</h3><p class="text-sm text-ocean-text-muted">HuggingFace's library for running ML models in the browser. Powers Chrome extension and Next.js web inference with ONNX models.</p></a><a href="https://github.com/ggerganov/llama.cpp" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">llama.cpp</h3><p class="text-sm text-ocean-text-muted">High-performance C++ inference engine for GGUF models. Used on mobile (via llama.rn JSI bindings) and desktop (via Rust llama-cpp-2 crate).</p></a><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">WebGPU</h3><p class="text-sm text-ocean-text-muted">Next-generation GPU API for the web, enabling high-performance computation directly on your graphics hardware in browsers.</p></a><a href="https://onnxruntime.ai/" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">ONNX Runtime Web</h3><p class="text-sm text-ocean-text-muted">Microsoft's cross-platform inference engine, optimized for WebGPU and WASM execution in browser environments.</p></a><a href="https://tauri.app/" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">Tauri</h3><p class="text-sm text-ocean-text-muted">Build lightweight desktop apps with a Rust backend and system WebView. No bundled Chromium â dramatically smaller than Electron.</p></a><a href="https://expo.dev/" target="_blank" rel="noopener noreferrer" class="rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40"><h3 class="mb-2 font-semibold text-ocean-text">Expo + React Native</h3><p class="text-sm text-ocean-text-muted">Cross-platform mobile framework. Combined with llama.rn's JSI bindings for near-native LLM inference on iOS and Android.</p></a></div></div></section><section class="px-4 py-12 text-center sm:px-6 sm:py-16"><h2 class="mb-4 text-2xl font-bold text-ocean-text sm:text-3xl">Ready to try it?</h2><p class="mx-auto mb-6 max-w-lg text-ocean-text-muted">Start chatting with AI directly in your browser. No sign-up required, no data collected, completely free.</p><div class="flex flex-col items-center justify-center gap-3 sm:flex-row sm:gap-4"><a data-slot="button" class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='
1size-'])]:size-4 shadow-xs h-10 rounded-md px-6 has-[>svg]:px-4 bg-ocean-deep text-white hover:bg-ocean-deep/90 dark:text-ocean-abyss" href="/chat">Try the Demo</a><a href="https://github.com/tantara/transformers.js-chrome" target="_blank" rel="noopener noreferrer" data-slot="button" class="focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shadow-xs h-10 rounded-md px-6 has-[>svg]:px-4 border border-ocean-mid/30 bg-white/80 text-ocean-text hover:bg-white dark:border-white/20 dark:bg-black/40 dark:text-white">View on GitHub</a></div></section></main><footer class="bg-ocean-abyss border-t border-white/10"><div class="container px-4 py-8 sm:px-6 sm:py-12"><div class="grid grid-cols-2 gap-6 sm:gap-8 md:grid-cols-4"><div class="col-span-2 md:col-span-1"><a class="flex items-center gap-2 font-semibold text-white" href="/"><img alt="TinyWhale logo" loading="lazy" width="28" height="28" decoding="async" data-nimg="1" style="color:transparent" src="/logo.svg"/><span>TinyWhale</span></a><p class="mt-3 text-sm text-white/60">AI inference in your browser. No server, no data leaves your machine.</p></div><div><h3 class="mb-3 text-sm font-semibold uppercase tracking-wider text-white/80">Product</h3><ul class="space-y-2"><li><a class="text-sm text-white/50 transition-colors hover:text-white" href="/">Web Demo</a></li><li><a href="https://chromewebstore.google.com/detail/private-ai-assistant-runn/jojlpeliekadmokfnikappfadbjiaghp?authuser=0&hl=en" target="_blank" rel="noopener noreferrer" class="text-sm text-white/50 transition-colors hover:text-white">Chrome Extension</a></li><li><a href="https://github.com/tantara/transformers.js-chrome" target="_blank" rel="noopener noreferrer" class="text-sm text-white/50 transition-colors hover:text-white">Mobile App</a></li><li><a href="https://github.com/tantara/transformers.js-chrome" target="_blank" rel="noopener noreferrer" class="text-sm text-white/50 transition-colors hover:text-white">Desktop App</a></li></ul></div><div><h3 class="mb-3 text-sm font-semibold uppercase tracking-wider text-white/80">Resources</h3><ul class="space-y-2"><li><a class="text-sm text-white/50 transition-colors hover:text-white" href="/how-it-works">How It Works</a></li></ul></div><div><h3 class="mb-3 text-sm font-semibold uppercase tracking-wider text-white/80">Community</h3><ul class="space-y-2"><li><a href="https://github.com/tantara/transformers.js-chrome" target="_blank" rel="noopener noreferrer" class="text-sm text-white/50 transition-colors hover:text-white">GitHub</a></li><li><a href="https://github.com/tantara/transformers.js-chrome/issues" target="_blank" rel="noopener noreferrer" class="text-sm text-white/50 transition-colors hover:text-white">Report a Bug</a></li></ul></div></div><div class="mt-10 flex flex-col items-center justify-between border-t border-white/10 pt-6 text-sm text-white/40 sm:flex-row"><p>Built in the browser, for the browser.</p><p>© <!-- -->2026<!-- --> TinyWhale. All rights reserved.</p></div></div></footer></div><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><!--$!--><template data-dgst="BAILOUT_TO_CLIENT_SIDE_RENDERING"></template><!--/$-->
1<script src="/_next/static/chunks/086b243adc657d55.js" id="_R_" async=""></script>
1<script>(self.__next_f=self.__next_f||[]).push([0])</script>
1<script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[75656,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\"],\"ThemeProvider\"]\n3:I[75653,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"default\"]\n4:I[36114,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"default\"]\n5:I[89447,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\"],\"Toaster\"]\n6:I[57627,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\"],\"Analytics\"]\n7:I[30183,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\",\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/67480a1d5392c377.js\"],\"Navbar\"]\n13:I[49786,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"default\"]\n:HL[\"/_next/static/chunks/e78bca1c67f3c6b8.css\",\"style\"]\n:HL[\"/_next/static/media/68d403cf9f2c68c5-s.p.f9f15f61.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/70bc3e132a0a741e-s.p.15008bfb.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/83afe278b6a6bb3c-s.p.3a6ba036.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n"])</script>
1<script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"NvkFI3K3JcWeGnty8vGQq\",\"c\":[\"\",\"how-it-works\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"how-it-works\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/e78bca1c67f3c6b8.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/c117910d669fdd7f.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/d2efd6138645d809.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"bg-background text-foreground min-h-screen font-sans antialiased inter_dd475d0c-module__9A3jha__variable source_serif_4_81d6187e-module__GRic1G__variable jetbrains_mono_9a7616cc-module__ve5NeG__variable\",\"children\":[\"$\",\"$L2\",null,{\"children\":[[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L5\",null,{}],[\"$\",\"$L6\",null,{}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"className\":\"flex min-h-screen flex-col bg-ocean-foam text-ocean-text\",\"children\":[[\"$\",\"$L7\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1\",\"children\":[[\"$\",\"section\",null,{\"className\":\"px-4 pt-28 pb-12 text-center sm:px-6 sm:pt-32 sm:pb-16\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"mb-4 text-3xl font-bold tracking-tight text-ocean-text sm:text-4xl md:text-5xl\",\"children\":\"How It Works\"}],[\"$\",\"p\",null,{\"className\":\"mx-auto max-w-2xl text-base text-ocean-text-muted sm:text-lg\",\"children\":\"TinyWhale runs LLMs entirely on your device â across Chrome extensions, browsers, mobile apps, and desktop. No servers, no cloud, no data collection.\"}]]}],[\"$\",\"section\",null,{\"className\":\"px-4 pb-12 sm:px-6 sm:pb-16\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto grid max-w-4xl gap-6 sm:gap-8 md:grid-cols-3\",\"children\":[[\"$\",\"div\",\"01\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-8\",\"children\":[[\"$\",\"path\",null,{\"d\":\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"}],[\"$\",\"polyline\",null,{\"points\":\"7,10 12,15 17,10\"}],[\"$\",\"line\",null,{\"x1\":\"12\",\"x2\":\"12\",\"y1\":\"15\",\"y2\":\"3\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"mb-1 text-sm font-medium text-ocean-text-muted\",\"children\":[\"Step \",\"01\"]}],[\"$\",\"h3\",null,{\"className\":\"mb-2 text-lg font-semibold text-ocean-text\",\"children\":\"Load the Model\"}],[\"$\",\"p\",null,{\"className\":\"text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"An open source LLM (quantized to 4-bit) is downloaded directly into your browser. The model files are cached locally, so subsequent visits load instantly. The entire model is only ~500MB thanks to 4-bit quantization.\"}]]}],\"$L8\",\"$L9\"]}]}],\"$La\",\"$Lb\",\"$Lc\",\"$Ld\"]}],\"$Le\"]}],[\"$Lf\",\"$L10\"],\"$L11\"]}],{}
1,null,false,false]},null,false,false]},null,false,false],\"$L12\",false]],\"m\":\"$undefined\",\"G\":[\"$13\",[]],\"S\":true}\n"])</script>
1<script>self.__next_f.push([1,"19:I[70275,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\",\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/67480a1d5392c377.js\"],\"\"]\n1a:I[75277,[\"/_next/static/chunks/c117910d669fdd7f.js\",\"/_next/static/chunks/d2efd6138645d809.js\",\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/67480a1d5392c377.js\"],\"Image\"]\n1b:I[4527,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"OutletBoundary\"]\n1c:\"$Sreact.suspense\"\n1e:I[4527,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"ViewportBoundary\"]\n20:I[4527,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"MetadataBoundary\"]\n8:[\"$\",\"div\",\"02\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-8\",\"children\":[[\"$\",\"rect\",null,{\"width\":\"18\",\"height\":\"11\",\"x\":\"3\",\"y\":\"11\",\"rx\":\"2\",\"ry\":\"2\"}],[\"$\",\"path\",null,{\"d\":\"M7 11V7a5 5 0 0 1 10 0v4\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"mb-1 text-sm font-medium text-ocean-text-muted\",\"children\":[\"Step \",\"02\"]}],[\"$\",\"h3\",null,{\"className\":\"mb-2 text-lg font-semibold text-ocean-text\",\"children\":\"Chat Privately\"}],[\"$\",\"p\",null,{\"className\":\"text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"All inference runs locally on your GPU via WebGPU. Your conversations never leave your device â there's no server, no API calls, no telemetry. Once loaded, it even works offline.\"}]]}]\n"])</script>
1<script>self.__next_f.push([1,"9:[\"$\",\"div\",\"03\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-8\",\"children\":[[\"$\",\"path\",null,{\"d\":\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"}],[\"$\",\"circle\",null,{\"cx\":\"12\",\"cy\":\"12\",\"r\":\"3\"}]]}]}],[\"$\",\"div\",null,{\"className\":\"mb-1 text-sm font-medium text-ocean-text-muted\",\"children\":[\"Step \",\"03\"]}],[\"$\",\"h3\",null,{\"className\":\"mb-2 text-lg font-semibold text-ocean-text\",\"children\":\"Customize \u0026 Explore\"}],[\"$\",\"p\",null,{\"className\":\"text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"Fine-tune generation with temperature, top-p, top-k, and more. Upload images for vision tasks â our models support multimodal input. Experiment with different settings to get the best results.\"}]]}]\n"])</script>
1<script>self.__next_f.push([1,"a:[\"$\",\"section\",null,{\"className\":\"bg-ocean-shallow px-4 py-12 sm:px-6 sm:py-16\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-5xl\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"mb-4 text-center text-2xl font-bold text-ocean-text sm:text-3xl\",\"children\":\"4 Platforms, One Monorepo\"}],[\"$\",\"p\",null,{\"className\":\"mx-auto mb-10 max-w-2xl text-center text-sm text-ocean-text-muted sm:text-base\",\"children\":\"Same goal â on-device LLM inference â but each platform uses different engines and model formats optimized for its runtime.\"}],[\"$\",\"div\",null,{\"className\":\"grid gap-6 md:grid-cols-2\",\"children\":[[\"$\",\"div\",\"Chrome Extension\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 flex items-center gap-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-6\",\"children\":[[\"$\",\"path\",null,{\"d\":\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"}],[\"$\",\"polyline\",null,{\"points\":\"15,3 21,3 21,9\"}],[\"$\",\"line\",null,{\"x1\":\"10\",\"x2\":\"21\",\"y1\":\"14\",\"y2\":\"3\"}]]}]}],[\"$\",\"div\",null,{\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-lg font-semibold text-ocean-text\",\"children\":\"Chrome Extension\"}],[\"$\",\"span\",null,{\"className\":\"inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20\",\"children\":\"Plasmo MV3\"}]]}]]}],[\"$\",\"p\",null,{\"className\":\"mb-4 text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"Run LLMs directly in a Chrome side panel. The service worker loads the model and streams tokens to the UI via chrome.runtime.sendMessage().\"}],[\"$\",\"div\",null,{\"className\":\"mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30\",\"children\":[[\"$\",\"div\",\"Inference Engine\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Inference Engine\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Transformers.js\"}]]}],[\"$\",\"div\",\"Model Format\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Model Format\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"ONNX (q4f16)\"}]]}],[\"$\",\"div\",\"GPU Acceleration\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"GPU Acceleration\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"WebGPU\"}]]}],[\"$\",\"div\",\"Execution Context\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Execution Context\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Service Worker\"}]]}],[\"$\",\"div\",\"Default Model\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs \",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Default Model\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Qwen3.5-0.8B\"}]]}]]}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"0\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Service worker requires build patches: import.meta.url rewriting, Node module stubs (fs, sharp, onnxruntime-node), and env.js patching for IS_BROW
1SER_ENV\"]}],[\"$\",\"li\",\"1\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Auto-detects WebGPU FP16 support (shader-f16) and falls back to q4 quantization when unavailable\"]}],\"$L14\",\"$L15\"]}]]}],\"$L16\",\"$L17\",\"$L18\"]}]]}]}]\n"])</script>
1<script>self.__next_f.push([1,"b:[\"$\",\"section\",null,{\"className\":\"px-4 py-12 sm:px-6 sm:py-16\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-5xl\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"mb-8 text-center text-2xl font-bold text-ocean-text sm:text-3xl\",\"children\":\"Platform Comparison\"}],[\"$\",\"div\",null,{\"className\":\"overflow-x-auto rounded-xl border border-ocean-mid/20 bg-white/60 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[\"$\",\"table\",null,{\"className\":\"w-full text-sm\",\"children\":[[\"$\",\"thead\",null,{\"children\":[\"$\",\"tr\",null,{\"className\":\"border-b border-ocean-mid/20\",\"children\":[[\"$\",\"th\",null,{\"className\":\"px-4 py-3 text-left font-medium text-ocean-text-muted\"}],[\"$\",\"th\",null,{\"className\":\"px-4 py-3 text-left font-semibold text-ocean-text\",\"children\":\"Chrome Extension\"}],[\"$\",\"th\",null,{\"className\":\"px-4 py-3 text-left font-semibold text-ocean-text\",\"children\":\"Browser\"}],[\"$\",\"th\",null,{\"className\":\"px-4 py-3 text-left font-semibold text-ocean-text\",\"children\":\"Mobile\"}],[\"$\",\"th\",null,{\"className\":\"px-4 py-3 text-left font-semibold text-ocean-text\",\"children\":\"Desktop\"}]]}]}],[\"$\",\"tbody\",null,{\"children\":[[\"$\",\"tr\",\"Inference Engine\",{\"className\":\"border-b border-ocean-mid/10\",\"children\":[[\"$\",\"td\",null,{\"className\":\"px-4 py-3 font-medium text-ocean-text-muted\",\"children\":\"Inference Engine\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Transformers.js\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Transformers.js\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"llama.cpp (JSI)\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"llama.cpp (Rust)\"}]]}],[\"$\",\"tr\",\"Model Format\",{\"className\":\"border-b border-ocean-mid/10\",\"children\":[[\"$\",\"td\",null,{\"className\":\"px-4 py-3 font-medium text-ocean-text-muted\",\"children\":\"Model Format\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"ONNX\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"ONNX\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"GGUF\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"GGUF\"}]]}],[\"$\",\"tr\",\"GPU Acceleration\",{\"className\":\"border-b border-ocean-mid/10\",\"children\":[[\"$\",\"td\",null,{\"className\":\"px-4 py-3 font-medium text-ocean-text-muted\",\"children\":\"GPU Acceleration\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"WebGPU\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"WebGPU\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Metal / OpenCL\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"CPU + GPU\"}]]}],[\"$\",\"tr\",\"Execution Context\",{\"className\":\"border-b border-ocean-mid/10\",\"children\":[[\"$\",\"td\",null,{\"className\":\"px-4 py-3 font-medium text-ocean-text-muted\",\"children\":\"Execution Context\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Service Worker\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Web Worker\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Native Thread\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Rust Thread\"}]]}],[\"$\",\"tr\",\"Installation\",{\"className\":\"\",\"children\":[[\"$\",\"td\",null,{\"className\":\"px-4 py-3 font-medium text-ocean-text-muted\",\"children\":\"Installation\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Chrome Web Store\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"None (URL)\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"App Store\"}],[\"$\",\"td\",null,{\"className\":\"px-4 py-3 text-ocean-text\",\"children\":\"Download\"}]]}]]}]]}]}]]}]}]\n"])</script>
1<script>self.__next_f.push([1,"c:[\"$\",\"section\",null,{\"className\":\"bg-ocean-shallow px-4 py-12 sm:px-6 sm:py-16\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-5xl\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"mb-8 text-center text-2xl font-bold text-ocean-text sm:text-3xl\",\"children\":\"Technology Stack\"}],[\"$\",\"div\",null,{\"className\":\"grid gap-6 sm:grid-cols-2 lg:grid-cols-3\",\"children\":[[\"$\",\"a\",\"Transformers.js\",{\"href\":\"https://huggingface.co/docs/transformers.js\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"Transformers.js\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"HuggingFace's library for running ML models in the browser. Powers Chrome extension and Next.js web inference with ONNX models.\"}]]}],[\"$\",\"a\",\"llama.cpp\",{\"href\":\"https://github.com/ggerganov/llama.cpp\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"llama.cpp\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"High-performance C++ inference engine for GGUF models. Used on mobile (via llama.rn JSI bindings) and desktop (via Rust llama-cpp-2 crate).\"}]]}],[\"$\",\"a\",\"WebGPU\",{\"href\":\"https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"WebGPU\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"Next-generation GPU API for the web, enabling high-performance computation directly on your graphics hardware in browsers.\"}]]}],[\"$\",\"a\",\"ONNX Runtime Web\",{\"href\":\"https://onnxruntime.ai/\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"ONNX Runtime Web\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"Microsoft's cross-platform inference engine, optimized for WebGPU and WASM execution in browser environments.\"}]]}],[\"$\",\"a\",\"Tauri\",{\"href\":\"https://tauri.app/\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"Tauri\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"Build lightweight desktop apps with a Rust backend and system WebView. No bundled Chromium â dramatically smaller than Electron.\"}]]}],[\"$\",\"a\",\"Expo + React Native\",{\"href\":\"https://expo.dev/\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm transition-colors hover:border-ocean-deep/40 dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-2 font-semibold text-ocean-text\",\"children\":\"Expo + React Native\"}],[\"$\",\"p\",null,{\"className\":\"text-sm text-ocean-text-muted\",\"children\":\"Cross-platform mobile framework. Combined with llama.rn's JSI bindings for near-native LLM inference on iOS and Android.\"}]]}]]}]]}]}]\n"])</script>
1<script>self.__next_f.push([1,"d:[\"$\",\"section\",null,{\"className\":\"px-4 py-12 text-center sm:px-6 sm:py-16\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"mb-4 text-2xl font-bold text-ocean-text sm:text-3xl\",\"children\":\"Ready to try it?\"}],[\"$\",\"p\",null,{\"className\":\"mx-auto mb-6 max-w-lg text-ocean-text-muted\",\"children\":\"Start chatting with AI directly in your browser. No sign-up required, no data collected, completely free.\"}],[\"$\",\"div\",null,{\"className\":\"flex flex-col items-center justify-center gap-3 sm:flex-row sm:gap-4\",\"children\":[[\"$\",\"$L19\",null,{\"href\":\"/chat\",\"children\":\"Try the Demo\",\"data-slot\":\"button\",\"className\":\"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [\u0026_svg]:pointer-events-none [\u0026_svg]:shrink-0 [\u0026_svg:not([class*='size-'])]:size-4 shadow-xs h-10 rounded-md px-6 has-[\u003esvg]:px-4 bg-ocean-deep text-white hover:bg-ocean-deep/90 dark:text-ocean-abyss\",\"ref\":null}],[\"$\",\"a\",null,{\"href\":\"https://github.com/tantara/transformers.js-chrome\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"children\":\"View on GitHub\",\"data-slot\":\"button\",\"className\":\"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [\u0026_svg]:pointer-events-none [\u0026_svg]:shrink-0 [\u0026_svg:not([class*='size-'])]:size-4 shadow-xs h-10 rounded-md px-6 has-[\u003esvg]:px-4 border border-ocean-mid/30 bg-white/80 text-ocean-text hover:bg-white dark:border-white/20 dark:bg-black/40 dark:text-white\",\"ref\":null}]]}]]}]\n"])</script>
1<script>self.__next_f.push([1,"e:[\"$\",\"footer\",null,{\"className\":\"bg-ocean-abyss border-t border-white/10\",\"children\":[\"$\",\"div\",null,{\"className\":\"container px-4 py-8 sm:px-6 sm:py-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"grid grid-cols-2 gap-6 sm:gap-8 md:grid-cols-4\",\"children\":[[\"$\",\"div\",null,{\"className\":\"col-span-2 md:col-span-1\",\"children\":[[\"$\",\"$L19\",null,{\"href\":\"/\",\"className\":\"flex items-center gap-2 font-semibold text-white\",\"children\":[[\"$\",\"$L1a\",null,{\"src\":\"/logo.svg\",\"alt\":\"TinyWhale logo\",\"width\":28,\"height\":28,\"className\":\"$undefined\"}],[\"$\",\"span\",null,{\"children\":\"TinyWhale\"}]]}],[\"$\",\"p\",null,{\"className\":\"mt-3 text-sm text-white/60\",\"children\":\"AI inference in your browser. No server, no data leaves your machine.\"}]]}],[[\"$\",\"div\",\"Product\",{\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-3 text-sm font-semibold uppercase tracking-wider text-white/80\",\"children\":\"Product\"}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"Web Demo\",{\"children\":[\"$\",\"$L19\",null,{\"href\":\"/\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"Web Demo\"}]}],[\"$\",\"li\",\"Chrome Extension\",{\"children\":[\"$\",\"a\",null,{\"href\":\"https://chromewebstore.google.com/detail/private-ai-assistant-runn/jojlpeliekadmokfnikappfadbjiaghp?authuser=0\u0026hl=en\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"Chrome Extension\"}]}],[\"$\",\"li\",\"Mobile App\",{\"children\":[\"$\",\"a\",null,{\"href\":\"https://github.com/tantara/transformers.js-chrome\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"Mobile App\"}]}],[\"$\",\"li\",\"Desktop App\",{\"children\":[\"$\",\"a\",null,{\"href\":\"https://github.com/tantara/transformers.js-chrome\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"Desktop App\"}]}]]}]]}],[\"$\",\"div\",\"Resources\",{\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-3 text-sm font-semibold uppercase tracking-wider text-white/80\",\"children\":\"Resources\"}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"How It Works\",{\"children\":[\"$\",\"$L19\",null,{\"href\":\"/how-it-works\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"How It Works\"}]}]]}]]}],[\"$\",\"div\",\"Community\",{\"children\":[[\"$\",\"h3\",null,{\"className\":\"mb-3 text-sm font-semibold uppercase tracking-wider text-white/80\",\"children\":\"Community\"}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"GitHub\",{\"children\":[\"$\",\"a\",null,{\"href\":\"https://github.com/tantara/transformers.js-chrome\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"GitHub\"}]}],[\"$\",\"li\",\"Report a Bug\",{\"children\":[\"$\",\"a\",null,{\"href\":\"https://github.com/tantara/transformers.js-chrome/issues\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm text-white/50 transition-colors hover:text-white\",\"children\":\"Report a Bug\"}]}]]}]]}]]]}],[\"$\",\"div\",null,{\"className\":\"mt-10 flex flex-col items-center justify-between border-t border-white/10 pt-6 text-sm text-white/40 sm:flex-row\",\"children\":[[\"$\",\"p\",null,{\"children\":\"Built in the browser, for the browser.\"}],[\"$\",\"p\",null,{\"children\":[\"© \",2026,\" TinyWhale. All rights reserved.\"]}]]}]]}]}]\n"])</script>
1<script>self.__next_f.push([1,"f:[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"async\":true,\"nonce\":\"$undefined\"}]\n10:[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/67480a1d5392c377.js\",\"async\":true,\"nonce\":\"$undefined\"}]\n11:[\"$\",\"$L1b\",null,{\"children\":[\"$\",\"$1c\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@1d\"}]}]\n12:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L1e\",null,{\"children\":\"$@1f\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L20\",null,{\"children\":[\"$\",\"$1c\",null,{\"name\":\"Next.Metadata\",\"children\":\"$@21\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\n"])</script>
1<script>self.__next_f.push([1,"14:[\"$\",\"li\",\"2\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Supports Firefox MV2 (sidebar_action) and Safari (Xcode conversion) from the same codebase\"]}]\n15:[\"$\",\"li\",\"3\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Models include text generation (Llama, Qwen, Phi, SmolLM, DeepSeek-R1), vision (Qwen VL, Janus), and speech-to-text (Whisper)\"]}]\n"])</script>
1<script>self.__next_f.push([1,"16:[\"$\",\"div\",\"Browser\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 flex items-center gap-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-6\",\"children\":[[\"$\",\"circle\",null,{\"cx\":\"12\",\"cy\":\"12\",\"r\":\"10\"}],[\"$\",\"path\",null,{\"d\":\"M2 12h20\"}],[\"$\",\"path\",null,{\"d\":\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"}]]}]}],[\"$\",\"div\",null,{\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-lg font-semibold text-ocean-text\",\"children\":\"Browser\"}],[\"$\",\"span\",null,{\"className\":\"inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20\",\"children\":\"Next.js\"}]]}]]}],[\"$\",\"p\",null,{\"className\":\"mb-4 text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"In-browser AI chat using a Web Worker to keep the main thread responsive. The LLMPipeline singleton loads the model once and handles both text-only and vision (image+text) inference.\"}],[\"$\",\"div\",null,{\"className\":\"mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30\",\"children\":[[\"$\",\"div\",\"Inference Engine\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Inference Engine\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Transformers.js\"}]]}],[\"$\",\"div\",\"Model Format\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Model Format\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"ONNX (q4f16)\"}]]}],[\"$\",\"div\",\"GPU Acceleration\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"GPU Acceleration\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"WebGPU (Web Worker)\"}]]}],[\"$\",\"div\",\"Execution Context\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Execution Context\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Web Worker\"}]]}],[\"$\",\"div\",\"Default Model\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs \",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Default Model\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Qwen3.5-0.8B\"}]]}]]}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"0\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Uses AutoModelForImageTextToText + AutoProcessor for unified text and vision inference in a single model\"]}],[\"$\",\"li\",\"1\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"TextStreamer provides real-time token streaming with TPS (tokens/sec) and TTFT (time to first token) metrics\"]}],[\"$\",\"li\",\"2\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"InterruptableStoppingCriteria allows users to stop generation mid-stream\"]}],[\"$\",\"li\",\"3\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"No build compatibility hacks needed â Web Workers support standard ES modules natively\"]}]]}]]}]\n"])</script>
1<script>self.__next_f.push([1,"17:[\"$\",\"div\",\"Mobile\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 flex items-center gap-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-6\",\"children\":[[\"$\",\"rect\",null,{\"width\":\"14\",\"height\":\"20\",\"x\":\"5\",\"y\":\"2\",\"rx\":\"2\",\"ry\":\"2\"}],[\"$\",\"path\",null,{\"d\":\"M12 18h.01\"}]]}]}],[\"$\",\"div\",null,{\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-lg font-semibold text-ocean-text\",\"children\":\"Mobile\"}],[\"$\",\"span\",null,{\"className\":\"inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20\",\"children\":\"Expo + llama.rn\"}]]}]]}],[\"$\",\"p\",null,{\"className\":\"mb-4 text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"Native mobile inference using llama.rn, a React Native binding to llama.cpp via JSI (JavaScript Interface). GGUF models run with Metal GPU acceleration on iOS.\"}],[\"$\",\"div\",null,{\"className\":\"mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30\",\"children\":[[\"$\",\"div\",\"Inference Engine\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Inference Engine\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"llama.cpp (JSI)\"}]]}],[\"$\",\"div\",\"Model Format\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Model Format\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"GGUF\"}]]}],[\"$\",\"div\",\"GPU Acceleration\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"GPU Acceleration\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Metal (iOS) / OpenCL (Android)\"}]]}],[\"$\",\"div\",\"Execution Context\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Execution Context\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Native Thread\"}]]}],[\"$\",\"div\",\"Framework\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs \",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Framework\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Expo SDK 54\"}]]}]]}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"0\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"JSI bindings bypass the React Native Bridge for near-native performance â direct
1C++ to JavaScript calls\"]}],[\"$\",\"li\",\"1\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"iOS uses Metal with up to 99 GPU layers; Android supports CPU and optional OpenCL GPU offloading\"]}],[\"$\",\"li\",\"2\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"All llama.cpp symbols are prefixed with lm_ to prevent namespace conflicts with other native libraries\"]}],[\"$\",\"li\",\"3\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Supports multimodal (vision/audio), embeddings, grammar sampling (GBNF/JSON schema), and tool calling\"]}]]}]]}]\n"])</script>
1<script>self.__next_f.push([1,"18:[\"$\",\"div\",\"Desktop\",{\"className\":\"rounded-xl border border-ocean-mid/20 bg-white/60 p-6 shadow-sm backdrop-blur-sm dark:bg-ocean-abyss/40\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-4 flex items-center gap-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-ocean-deep\",\"children\":[\"$\",\"svg\",null,{\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 24 24\",\"fill\":\"none\",\"stroke\":\"currentColor\",\"strokeWidth\":1.5,\"strokeLinecap\":\"round\",\"strokeLinejoin\":\"round\",\"className\":\"size-6\",\"children\":[[\"$\",\"rect\",null,{\"width\":\"20\",\"height\":\"14\",\"x\":\"2\",\"y\":\"3\",\"rx\":\"2\"}],[\"$\",\"line\",null,{\"x1\":\"8\",\"x2\":\"16\",\"y1\":\"21\",\"y2\":\"21\"}],[\"$\",\"line\",null,{\"x1\":\"12\",\"x2\":\"12\",\"y1\":\"17\",\"y2\":\"21\"}]]}]}],[\"$\",\"div\",null,{\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-lg font-semibold text-ocean-text\",\"children\":\"Desktop\"}],[\"$\",\"span\",null,{\"className\":\"inline-block rounded-full bg-ocean-deep/10 px-2.5 py-0.5 text-xs font-medium text-ocean-deep dark:bg-ocean-deep/20\",\"children\":\"Tauri + Rust\"}]]}]]}],[\"$\",\"p\",null,{\"className\":\"mb-4 text-sm leading-relaxed text-ocean-text-muted\",\"children\":\"Lightweight desktop app with a Rust backend that calls llama.cpp directly via the llama-cpp-2 crate. Models are auto-downloaded from Hugging Face Hub with real-time progress tracking.\"}],[\"$\",\"div\",null,{\"className\":\"mb-4 rounded-lg border border-ocean-mid/10 bg-ocean-foam/50 dark:bg-ocean-abyss/30\",\"children\":[[\"$\",\"div\",\"Inference Engine\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Inference Engine\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"llama-cpp-2 (Rust)\"}]]}],[\"$\",\"div\",\"Model Format\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Model Format\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"GGUF\"}]]}],[\"$\",\"div\",\"GPU Acceleration\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"GPU Acceleration\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"CPU + optional GPU\"}]]}],[\"$\",\"div\",\"Execution Context\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs border-b border-ocean-mid/10\",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Execution Context\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Rust Thread\"}]]}],[\"$\",\"div\",\"Frontend\",{\"className\":\"flex items-center justify-between px-3 py-2 text-xs \",\"children\":[[\"$\",\"span\",null,{\"className\":\"text-ocean-text-muted\",\"children\":\"Frontend\"}],[\"$\",\"span\",null,{\"className\":\"font-medium text-ocean-text\",\"children\":\"Vite + React\"}]]}]]}],[\"$\",\"ul\",null,{\"className\":\"space-y-2\",\"children\":[[\"$\",\"li\",\"0\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Tauri uses the system WebView instead of bundling Chromium â dramatically smaller app size vs Electron\"]}],[\"$\",\"li\",\"1\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Rust backend manages model lifecycle with Arc\u003cMutex\u003cModelStore\u003e\u003e for thread-safe concurrent access\"]}],[\"$\",\"li\",\"2\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Hugging Face Hub integration auto-discovers GGUF files and prefers q4_k_m quantization\"]}],[\"$\",\"li\",\"3\",{\"className\":\"flex gap-2 text-xs leading-relaxed text-ocean-text-muted\",\"children\":[[\"$\",\"span\",null,{\"className\":\"mt-1 block size-1 shrink-0 rounded-full bg-ocean-deep/60\"}],\"Download progress events are emitted via Tauri IPC to the React frontend in real-time\"]}]]}]]}]\n"])</script>
1<script>self.__next_f.push([1,"1f:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"media\":\"(prefers-color-scheme: light)\",\"content\":\"white\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"media\":\"(prefers-color-scheme: dark)\",\"content\":\"black\"}]]\n"])</script>
1<script>self.__next_f.push([1,"22:I[89169,[\"/_next/static/chunks/2b1e452b2b1f7f3a.js\",\"/_next/static/chunks/2e6e09be009c86ac.js\"],\"IconMark\"]\n"])</script>
1<script>self.__next_f.push([1,"21:[[\"$\",\"title\",\"0\",{\"children\":\"How It Works | TinyWhale\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Learn how TinyWhale runs AI models on-device across Chrome extensions, browsers, mobile, and desktop using WebGPU, Transformers.js, and llama.cpp.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"author\",\"content\":\"TinyWhale\"}],[\"$\",\"meta\",\"3\",{\"name\":\"keywords\",\"content\":\"in-browser AI,WebGPU,browser AI,transformers.js,open source LLM,local LLM,private AI,ONNX,web inference\"}],[\"$\",\"meta\",\"4\",{\"name\":\"creator\",\"content\":\"TinyWhale\"}],[\"$\",\"meta\",\"5\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"meta\",\"6\",{\"name\":\"googlebot\",\"content\":\"index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:title\",\"content\":\"TinyWhale - In-Browser AI Chat\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:description\",\"content\":\"Chat with open source LLMs running entirely in your browser via WebGPU. No server, no data leaves your device.\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:url\",\"content\":\"https://tinywhale.dev\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:site_name\",\"content\":\"TinyWhale\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:locale\",\"content\":\"en_US\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://tinywhale.dev/og-image.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:image:alt\",\"content\":\"TinyWhale - In-Browser AI Chat\"}],[\"$\",\"meta\",\"16\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:creator\",\"content\":\"@tantara\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:title\",\"content\":\"TinyWhale - In-Browser AI Chat\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:description\",\"content\":\"Chat with open source LLMs running entirely in your browser via WebGPU. No server, no data leaves your device.\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image\",\"content\":\"https://tinywhale.dev/og-image.png\"}],[\"$\",\"link\",\"22\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"23\",{\"rel\":\"icon\",\"href\":\"/favicon-32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"24\",{\"rel\":\"icon\",\"href\":\"/favicon-16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"25\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$L22\",\"26\",{}]]\n"])</script>
1<script>self.__next_f.push([1,"1d:null\n"])</script>
1</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.