Worker Setup (Optional) โ
By default, Dendrite runs the LLM engine on the main thread. This works out of the box with zero setup.
For better performance โ especially during model loading and long conversations โ you can offload the engine to a Web Worker. This keeps the main thread responsive.
When to Use a Worker โ
| Scenario | Worker? |
|---|---|
| Quick prototype / testing | No โ default is fine |
| Production chat UI | Yes โ smoother UX |
| Long conversations (10+ turns) | Yes โ main thread stays responsive |
| Simple single-response use | No โ overhead not worth it |
Setup โ
1. Create a Worker File โ
Create worker.ts (or worker.js) in your project:
// worker.ts
import { WebWorkerMLCEngineHandler } from '@mlc-ai/web-llm'
const handler = new WebWorkerMLCEngineHandler()
self.onmessage = (msg: MessageEvent) => handler.onmessage(msg)INFO
This is the only place in your code that touches @mlc-ai/web-llm directly. Dendrite handles everything else.
2. Pass to createNeuron โ
const neuron = createNeuron({
modelId: 'gemma-2-2b-it-q4f16_1-MLC',
worker: new Worker(
new URL('./worker.ts', import.meta.url),
{ type: 'module' }
),
})The new URL('./worker.ts', import.meta.url) pattern works with Vite, Webpack 5, and most modern bundlers.
Worker Factory โ
If you need to create fresh workers (e.g., after model switching), pass a factory function:
worker: () => new Worker(
new URL('./worker.ts', import.meta.url),
{ type: 'module' }
)Without a Worker โ
If you don't pass worker, Dendrite uses CreateMLCEngine (main thread mode). This is the default and requires no extra files:
// This just works โ no worker needed
const neuron = createNeuron({
modelId: 'gemma-2-2b-it-q4f16_1-MLC',
systemPrompt: 'You are a pirate.',
})Framework Notes โ
Vite (Vue, React, Svelte) โ
Works out of the box. Place worker.ts anywhere in src/.
Next.js โ
Place the worker in public/worker.js (compiled JS, not TS):
worker: new Worker('/worker.js', { type: 'module' })Webpack โ
With webpack 5, the new URL() pattern works natively:
worker: new Worker(
new URL('./worker.ts', import.meta.url),
{ type: 'module' }
)