跪拜 Guibai
← Back to the summary

Run DeepSeek-R1 Locally in the Browser with WebGPU and Zero API Costs

Stop topping up your API account — put the large model in your browser, usable even offline.

Foreword

While you're still adding money to your DeepSeek account, someone has already run the R1 model directly in the browser — no backend needed, no server needed, not even an internet connection needed.

This article takes you from zero to one, packing the distilled version of DeepSeek-R1 into the browser, using WebGPU to accelerate inference, without ever taking out an API Key.

Why do on-device inference?

The three mountains of calling APIs

Calling the DeepSeek / OpenAI API seems convenient, but there are three problems behind it:

Pain Point Explanation
Expensive Frequent calls accumulate significant costs, especially for long streaming conversations
Insecure Chat context is sent to a remote server with every request; data privacy cannot be guaranteed
Network-dependent Server downtime or network fluctuations directly crash the user experience

The idea of on-device models

Since both the problem and the answer are known, why not move the model directly to the user's local machine?

This project explores exactly that path:

Traditional model: Browser ──network──→ DeepSeek Server ──returns answer──→ Browser

This project:   Browser's internal GPU runs the model directly → returns answer

No network requests, no waiting in queues, and conversation history stays local forever.

Technical Panorama

Let's look at the key technologies involved in this project, summarized in one sentence:

Use React for the page, TailwindCSS for styling, Transformers.js to orchestrate the model, and WebGPU for inference computation.

React + TypeScript + TailwindCSS: The frontend foundation

// App.tsx core skeleton
function App() {
  const [status, setStatus] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loadingMessage, setLoadingMessage] = useState("");
  const [progressItems, setProgressItems] = useState([...]);

  const IS_WEBGPU_AVAILABLE = !!navigator.gpu;
  // ...
}

Why choose React over Vue?

TailwindCSS: No more writing CSS

TailwindCSS's core — utility classes. Writing CSS used to be:

/* Traditional approach: name a class → write a selector → declare properties */
.my-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 1rem;
}

Now you just need:

<div className="flex flex-col items-center mb-1 max-w-[400px] text-center">

TailwindCSS provides a bunch of extremely semantic class names; flex is flex, text-center is centered text — what you see is what you get, almost eliminating the need to switch back and forth between hand-written CSS and the editor window. This is particularly useful in AI-driven Vibe Coding scenarios — LLMs are extremely good at this "tell you the class name, you assemble it yourself" pattern.

WebGPU: The GPU in the browser

This is the most hardcore part of the entire project.

Web frontends previously could only use WebGL (a 2011 standard), with limited performance. WebGPU is the new generation browser GPU API, directly comparable to Vulkan/Metal/DX12, allowing the browser to reap the benefits of modern GPUs.

// One line of code to detect if the browser supports WebGPU
const IS_WEBGPU_AVAILABLE = !!navigator.gpu;
//            ↑ Returns undefined when not supported
//           ↑ Double negation converts to explicit true/false

Currently supported by Chrome/Edge 113+, with Firefox following in Nightly builds.

Transformers.js: Bringing HuggingFace into the browser

This is the official JS library from HuggingFace, allowing you to:

// Typical workflow for loading a model with Transformers.js (pseudocode)
const pipeline = await pipeline('text-generation', modelName, {
  device: 'webgpu',  // Key: specifies running on GPU
});

Once loaded, everything runs completely locally; data never leaves the browser.

Model Selection

This project uses DeepSeek-R1-Distill-Qwen-1.5B-ONNX, with two key pieces of information:

Attribute Meaning
Distill Use the original DeepSeek-R1 to teach a small model, allowing it to retain reasoning ability while drastically reducing parameter count
1.5B (1.5 billion parameters) A fraction of the parameter count of cloud-based large models, but sufficient to complete many reasoning tasks locally

Small parameter models are not "crippled versions" — on specific tasks, a distilled small model can often achieve 90% of the effect with 1/10th of the compute.

Project Component Hierarchy

App.tsx (Main Component)
├── WebGPU Detection    → Prompt user if not supported
├── State Management    → null → loading → ready
├── Model Loading Area  → Progress bar, file info
├── Chat Area           → Input box + inference results
└── Error Handling Area → Friendly prompt when loading fails

The entire application is a single React functional component — before returning JSX is JavaScript logic, after return is the UI. This is the essence of React componentization.

Frontend Direct API Call vs BFF vs On-device Inference

Reviewing three architectural patterns:

① Frontend direct API call (Pure frontend)
  Browser ──fetch──→ DeepSeek API
  Problem: API Key is exposed in frontend code, visible with a right-click

② BFF pattern (Add an intermediate layer)
  Browser ──fetch──→ BFF (Your backend) ──→ DeepSeek API
  Problem: An extra backend to maintain, API costs still incurred

③ On-device inference (This project)
  Browser's internal GPU runs the model directly
  Advantages: Zero cost, zero latency (inference part), data never leaves the browser

Summary

The core value of this project is proving that the browser is not just a "presentation layer"; it is already a complete computing platform.

Tech stack review:

Layer Technology Responsibility
Interface React + TypeScript Componentized UI, state management
Styling TailwindCSS Atomic CSS, zero hand-written
Model Orchestration Transformers.js Load / call HuggingFace models
Inference Acceleration WebGPU + ONNX Runtime In-browser GPU computation

If you are a frontend engineer, this project can help you understand the full picture of the frontend tech stack in the AI era. If you want to put it on your resume, this project covers React, TypeScript, TailwindCSS, WebGPU, Transformers.js — all the hottest keywords right now.


Project Address: ai_doubao_dcx: Towards AGI, towards Doubao

How to run: pnpm install && pnpm dev

Browser requirement: Chrome/Edge 113+