惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
美团技术团队
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
L
LangChain Blog
雷峰网
雷峰网
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
腾讯CDC
Recent Announcements
Recent Announcements
The Register - Security
The Register - Security
有赞技术团队
有赞技术团队
Blog — PlanetScale
Blog — PlanetScale
博客园 - Franky
博客园 - 司徒正美
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
C
Check Point Blog
小众软件
小众软件
V
Visual Studio Blog
V
V2EX
F
Full Disclosure
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
罗磊的独立博客
人人都是产品经理
人人都是产品经理
量子位
Apple Machine Learning Research
Apple Machine Learning Research
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
博客园_首页
Y
Y Combinator Blog
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
Recorded Future
Recorded Future
G
Google Developers Blog
Vercel News
Vercel News
大猫的无限游戏
大猫的无限游戏
Microsoft Azure Blog
Microsoft Azure Blog
U
Unit 42
爱范儿
爱范儿
Jina AI
Jina AI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Supercharge your web app with free AI that runs in your users' browser
Petr Pátek · 2026-06-21 · via DEV Community

Petr Pátek

There is a class of feature that used to be impossible to ship for free: anything that needed a language model. You wired up an API key, you ate the per-token bill, and every prompt your users typed went off to someone else's server. For a small public tool, that math usually killed the idea before it started.

That changed. Recent versions of Chrome ship a language model, Gemini Nano, and expose it to any web page through the Prompt API. The model runs on the user's own machine. No API key. No inference bill. No data leaving the browser.

We put this into a real, live tool, a free Mermaid diagram editor where you describe a diagram in plain English and the browser writes the Mermaid code for you. This post is the developer's version of that story: how the API actually works, the code that makes a small on-device model trustworthy, and an honest accounting of what you gain and what you give up.

What "AI in the browser" means in 2026

The important word is built-in. This is not WebGPU plus a 4 GB model you download and run yourself. The model ships with Chrome, and you talk to it through a small standard-track JavaScript API.

As of Chrome 148, the Prompt API is stable for web pages (it had been available to extensions since Chrome 138). It is the general-purpose member of a growing family of built-in APIs:

  • Prompt API (LanguageModel): general natural-language prompting, now multimodal (text, plus image and audio input).
  • Summarizer, Writer, Rewriter, Proofreader: task-specific, text-to-text.
  • Translator and Language Detector: backed by expert models, desktop only.

The Prompt API is the one you reach for when you need something the task APIs don't cover, like "turn this description into Mermaid source." So that is the one this post focuses on.

The 15-line version

Here is the whole happy path. Check availability, create a session, prompt it.

// Feature-detect first. Old browsers won't have this at all.
if ('LanguageModel' in self) {
  const status = await LanguageModel.availability();

  if (status !== 'unavailable') {
    const session = await LanguageModel.create();
    const answer = await session.prompt('Explain event loops in one sentence.');
    console.log(answer);
    session.destroy();
  }
}

That is it. No keys, no SDK, no network call. The first time an origin uses the model, Chrome downloads it; after that it is local and works offline.

availability() is the gate you build your UI around. It returns one of four states:

  • "unavailable": the device can't run it (too little disk, no supported hardware, unsupported options).
  • "downloadable": supported, but the model needs downloading first. Requires a user gesture to start.
  • "downloading": a download is in progress.
  • "available": ready right now.

The real case study: plain text to a valid diagram

Mermaid is a tiny text language: A --> B becomes a flowchart. It's great once you know it, and forgettable if you only touch it monthly. The obvious fix is to let people describe the diagram and have the model write the Mermaid. The non-obvious part is making a small model's output trustworthy.

Gemini Nano is small. Prompt it for code and it will sometimes wrap the output in markdown fences, add a chatty preamble, or emit a diagram with a subtle syntax error. If you pipe that straight into your renderer, you ship a tool that breaks every fifth try.

The fix is to treat the model as a drafter and put a real validator in front of the user. Mermaid ships its own parser, so we use it as the source of truth:

const clean = (s) => s.replace(/```
{% endraw %}
(?:mermaid)?/g, '').trim();

async function describeToMermaid(description) {
  if ((await LanguageModel.availability()) === 'unavailable') return null;

  const session = await LanguageModel.create({
    initialPrompts: [{
      role: 'system',
      content:
        'You write Mermaid diagram source. Output only valid Mermaid code. ' +
        'No prose, no explanations, no markdown fences.',
    }],
  });

  try {
    let code = clean(await session.prompt({% raw %}`Create a Mermaid diagram: ${description}`{% endraw %}));

    // Source of truth: Mermaid's own parser, not the model's confidence.
    try {
      await mermaid.parse(code);
    } catch (err) {
      // Exactly one self-correction pass. Hand the error back to the model.
      code = clean(await session.prompt(
        {% raw %}`That Mermaid failed to parse:\n${err.message}\n`{% endraw %} +
        {% raw %}`Return corrected Mermaid only.`{% endraw %}
      ));
      await mermaid.parse(code); // still broken? this throws, caller handles it
    }

    return code;
  } finally {
    session.destroy(); // free the model; sessions are not free to hold open
  }
}
{% raw %}

That validate-and-retry loop is the difference between a demo and a tool. The model gets one chance to fix its own mistake. If it fails twice, we show a friendly message and leave the editor untouched rather than rendering garbage. The parser is the authority; the model is just a fast first draft.

If you can express the shape, constrain it

For outputs that are structured, you don't have to hope. The Prompt API accepts a JSON Schema via responseConstraint, and the model is forced to match it:


js
const schema = { type: 'boolean' };

const result = await session.prompt(
  `Is this text describing a sequence of steps?\n\n${input}`,
  { responseConstraint: schema }
);
console.log(JSON.parse(result)); // true | false


Mermaid source isn't cleanly expressible as JSON Schema, which is exactly why we lean on the parser instead. But for classification, extraction, or form-filling, structured output removes a whole category of cleanup code.

Ship it as progressive enhancement, never a wall

This is the part most people get wrong. On-device AI is a bonus for capable machines, not a baseline you can assume. So gate the feature, never the app.

In our editor, the entire tool, the live preview, themes, export, sharing, works in any modern browser. The Generate-from-text box only appears when the model reports itself usable. Everyone else sees a normal editor and never knows a feature was missing.


js
async function setupAI(generateButton) {
  if (!('LanguageModel' in self)) return; // not Chrome, or too old

  const status = await LanguageModel.availability();
  if (status === 'unavailable') return;

  generateButton.hidden = false;

  generateButton.onclick = async () => {
    // Model download needs a user gesture; this click is it.
    const session = await LanguageModel.create({
      monitor(m) {
        m.addEventListener('downloadprogress', (e) => {
          showProgress(Math.round(e.loaded * 100)); // multi-GB first time
        });
      },
    });
    // ...use the session...
  };
}


Two details that bite people:

  • User activation. If the model still needs downloading, create() must run inside a real user gesture (a click, key press, tap). Calling it on page load throws. Check navigator.userActivation.isActive if you're unsure.
  • The first download is large. It's a multi-gigabyte model. Listen for downloadprogress and tell the user, or your "Generate" button looks frozen for minutes.

The gains

This is genuinely a new capability, and for the right feature it's hard to beat:

  • Free to run. No inference server, no API invoice, no rate limits to manage at peak. For a free public tool this is the whole game; it costs us nothing per use.
  • Private by construction. The prompt and the response never touch the network. No data is sent to Google or anyone else. For people sketching internal systems or sensitive workflows, "it physically can't leave your machine" is a stronger promise than any privacy policy.
  • Offline after first load. Once the model is on the device, the feature works on a plane.
  • Low latency, no cold starts. No round trip. For short prompts it feels instant.
  • No backend to secure. There is no key to leak, no proxy to rate-limit, no abuse surface. The attack surface of "AI that runs in the client" is refreshingly small.

The losses

Equally honest, because this is where the "just use it everywhere" dream dies:

  • Hardware requirements are steep. Chrome wants ~22 GB free disk space on the profile volume, and either a GPU with more than 4 GB of VRAM or a CPU with 16 GB+ RAM and 4+ cores. Plenty of real laptops don't clear that bar.
  • Desktop Chromium only. Chrome on desktop (Windows 10/11, macOS 13+, Linux) or ChromeOS on Chromebook Plus. Not on most phones, not on Safari, not on Firefox today. You are building for a slice of your audience.
  • A big first download. Multi-gigabyte, on first use. Great afterward, awkward the first time.
  • It's a small model. Gemini Nano is not Gemini Pro. It drifts, it forgets format instructions, it makes mistakes a frontier model wouldn't. You must wrap it in validation, as above. Treat raw output as a suggestion.
  • Limited context and languages. A modest context window (watch for QuotaExceededError and the contextoverflow event), and as of Chrome 149 the language model targets English, Spanish, Japanese, German, and French.
  • Still maturing on the web. The web Prompt API is stable but actively evolving; sampling parameters like temperature/topK are extension-only for now, and it isn't available in Web Workers yet.

So when should you actually use it?

The decision is mostly about whether the feature is essential or a bonus, and how sensitive the data is.

Reach for on-device AI when the feature can be progressive enhancement, when privacy is a real selling point, when the workload is small and frequent (classify, extract, rewrite, draft), and when you'd rather not run a backend at all. That describes a surprising amount of "nice to have" AI.

Stay server-side when the feature is core to every user, when you need a large or frontier model, when output quality must be consistent across all hardware, or when you need it on mobile and Safari today. And you don't have to choose forever: a common pattern is hybrid, run on-device when available and fall back to a cloud model otherwise. Chrome's docs cover a polyfill and a Firebase AI Logic fallback for exactly this.

For our Mermaid editor the choice was easy. The diagram generator is a bonus, the people who can run it get something delightful and private, and everyone else gets a fully working editor. Nobody hits a wall.

A bonus war story: the tainted canvas

One detail that cost us an afternoon and might save you one. Exporting the diagram to PNG meant drawing it onto a hidden canvas, and in Chrome it kept failing with Tainted canvases may not be exported.

The cause: Mermaid was rendering text labels inside an embedded HTML element (a foreignObject), and the browser treats that as a security taint on the canvas, which blocks export. The fix was to configure Mermaid to render labels as real SVG <text> instead of embedded HTML. Bonus: the text now survives PNG export cleanly and stays selectable in the SVG. If you ever see a tainted-canvas error on an export that looked entirely local, check for foreignObject first.

Try it, then go build something

The Mermaid editor is live and free. If you're on a recent desktop Chrome, describe a diagram and watch the browser write it, with nothing leaving your machine. If you're not, you still get a fast editor with live preview, themes, and export.

The broader point: a meaningful slice of the AI features you've been quoting backend costs for can now run for free in the client, with better privacy than your server ever offered. It won't fit every case, the hardware bar and browser support see to that, but when it fits, it fits beautifully.

This is the pragmatic view of AI we bring to client work, too. We're far more interested in AI that quietly does a real job than AI as a headline, and in custom software built around how you actually work. If you've got a workflow that needs its own small, sharp tool, we like that kind of problem.

Built by Bitvea. You handle business. We handle IT.