The JS/TS SDK (@qvac/sdk on npm) is the JavaScript/TypeScript client for QVAC.
It drives a Bare worker over bare-rpc, and exposes every
QVAC capability through a unified, type-safe API.
QVAC ships part of its Android and iOS binaries as separate packages that your app needs. Pass installMissingPrebuilds to the plugin to have npx expo prebuild add them, or add them yourself. See Install QVAC in the Expo tutorial.
Prebuild your project to generate the native files:
npx expo prebuild
Prebuild also links QVAC's native addons into react-native-bare-kit. Reinstalling packages clears them, so run npx expo prebuild again after an install before building.
// The SDK prints no logs by default. To see its client and server logs, run with// QVAC_CONFIG_PATH pointing at a config that sets "loggerConsoleOutput": true// (see the Quickstart docs).import { loadModel, LLAMA_3_2_1B_INST_Q4_0, completion, unloadModel } from '@qvac/sdk';try { // Load a model into memory const modelId = await loadModel({ modelSrc: LLAMA_3_2_1B_INST_Q4_0, onProgress: (p) => { const mb = (n) => (n / 1e6).toFixed(1); const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`; process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`); if (p.percentage >= 100) process.stderr.write('\n'); } }); // You can use the loaded model multiple times const history = [ { role: 'user', content: 'Explain quantum computing in one sentence' } ]; const result = completion({ modelId, history, stream: true }); for await (const token of result.tokenStream) { process.stdout.write(token); } // Unload model to free up system resources await unloadModel({ modelId });}catch (error) { console.error('✖', error); process.exit(1);}
A registry model's engine identifies the plugin that loads it, such as
llamacpp-completion or moss-transcribe. Its addon is a category used for
filtering and legacy metadata; it does not uniquely identify a plugin. Several
plugins can share a native addon package. Use engine when selecting a model's
capability or filtering registry results by plugin. Supported legacy registry
identifiers remain readable.
Follow these instructions to run any example in this documentation:
All examples are self-contained, runnable JavaScript scripts. Use the qvac-examples workspace created in this quickstart to store and run them as you explore this documentation.
Run each example with the indicated compatible JavaScript environment. QVAC supports Node.js, Expo, and in-process Bare via @qvac/inference. The examples are written in Node style and run on Node.js or Bun directly; to run them on Bare, see Running on Bare.
Some examples need companion files — sample audio, an image, or a config — that aren't part of the embedded code. These can be found in the same examples directory.
Some examples also provide a TypeScript version. If you want to run TS directly, install the required dev dependencies:
tsx strips the types and runs the file, so no tsconfig.json is needed. Save a companion module in TypeScript too — shared.ts, not shared.js — so the example's ./shared import resolves to it.
Provide a process global. Install bare-process and set it before using @qvac/inference:
import process from "bare-process";globalThis.process = process;
Register the plugins the example uses — Bare runs in-process and nothing auto-registers. See Runtime registration on Bare.
Here is the SDK quickstart adapted for Bare with @qvac/inference:
quickstart-adapted.ts
// The SDK's quickstart, adapted for Bare with @qvac/inference. Three edits: import// from `@qvac/inference` instead of `@qvac/sdk`, import `process` from bare-process// (Bare has no `process` global), and register the plugins this example uses// via `plugins([...])`.import process from 'bare-process'import { plugins, LLAMA_3_2_1B_INST_Q4_0 } from '@qvac/inference'import { llmPlugin } from '@qvac/inference/llamacpp-completion/plugin'const { loadModel, completion, unloadModel } = plugins([llmPlugin])// From here it is the same as the SDK's quickstart.const modelId = await loadModel({ modelSrc: LLAMA_3_2_1B_INST_Q4_0 })const history = [{ role: 'user', content: 'Explain quantum computing in one sentence' }]const result = completion({ modelId, history, stream: true })for await (const token of result.tokenStream) { process.stdout.write(token)}await unloadModel({ modelId, autoClose: true })
For running QVAC on Bare in production, use @qvac/inference — the Bare-only in-process engine. Select addons and register plugins explicitly. @qvac/bare-sdk is deprecated; last release is 0.18.2.