Cody Bontecou

Client-side AI with Nuxt Workers + Transformers.js

March 24, 2025 · 2 minute read · ai,nuxt,transformers,transformers.js

Youtube video for those that prefer video content.

This post walks you through an implementation of NLLB-200, Facebook's text-to-text translation model, in the browser.

Core Tools

  • Nuxt Workers: Offload AI tasks to Web Workers to prevent main-thread blocking.
  • Transformers.js: Run pre-trained models (translation, sentiment analysis) directly in the browser.

Project Setup

Let's start by creating a new project with the necessary dependencies.

  • Create the project:
npm create nuxt <project-name>
  • Change into project directory:
cd <project-name>

Dependencies

  • Install runtime dependencies:
npm install @xenova/transformers
  • Install nuxt-workers via module:
npx nuxi@latest module add nuxt-workers

Web-worker

Nuxt Workers looks for your web workers in the ~/workers/ directory.

Create translate.ts:

// workers/translate.ts

import { pipeline } from '@xenova/transformers'

const task = 'translation'
const model = 'Xenova/nllb-200-distilled-600M'

export async function translate(input: string) {
    const translator = await pipeline(task, model)
    const translation = await translator(input, {
        tgt_lang: 'spa_Latn',
        src_lang: 'eng_Latn',
    })

    return translation
}

Transformers.js pulls the model from HuggingFace and installs it into your browser session. Now you can interact with it via the pipeline function.

You can view task options on Huggingface.

nllb-200 relies on FLORES-200 language codes. See here for the full list of languages and their corresponding codes.

UI Integration

To use the pages directory, replace app.vue with the following:

// app.vue

<template>
    <NuxtPage />
</template>

Then create an index.vue file, hooking into our translate function:

// pages/index.vue

<script setup lang="ts">
const input = ref('Hello')
const message = ref()

async function runTranslate() {
    message.value = await translate(input.value)
}
</script>

<template>
    {{ message }}
    <input type="text" v-model="input" />
    <button @click="runTranslate">Translate</button>
</template>

Showcase

Simple and effective

Beyond Translation

Swap the model and task for:

Reponuxt-workers-transformersjs

Newsletter

Subscribe to get my latest content. No spam.