{"id":27570,"date":"2024-05-07T16:12:52","date_gmt":"2024-05-07T14:12:52","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=27570"},"modified":"2024-05-07T18:34:33","modified_gmt":"2024-05-07T16:34:33","slug":"tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/","title":{"rendered":"Tutorial: Easy Client-side AI Translator With Transformers.js &#8211; Codemotion"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Normally when we think of integrating an Artificial Intelligence model into a Web App, we immediately think of servers in Python or, even more often, cloud platform APIs. In this small guide, however, we want to explore a less trodden path: the possibility of including AI models directly in Web Apps for client-side use today thanks to JavaScript and the current Web Standards!<\/p>\n\n\n\n<p>But before we launch into the fantasy and the code, let&#8217;s introduce you to the main characters of this story.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-meet-the-transformers\"><strong>Meet the Transformers\u2026<\/strong><\/h2>\n\n\n\n<p>&#8220;Transformers&#8221; have revolutionized the field of natural language processing (NLP) and artificial intelligence: this architecture, based on the concept of &#8220;self-attention&#8221;, allows models to pay attention to different parts of a text simultaneously, thus capturing the <em>relations between words<\/em> even if they are distant in the sequence.<\/p>\n\n\n\n<p><strong>But what makes &#8220;Transformers&#8221; so special?<\/strong><\/p>\n\n\n\n<p>Unlike traditional <a href=\"https:\/\/www.codemotion.com\/magazine\/video\/deep-neural-networks\/\" target=\"_blank\" aria-label=\"sequential neural network (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">sequential neural network<\/a> models, such as recurrent neural networks (RNNs) or convolutional neural networks (CNNs), which process data sequentially, &#8220;Transformers&#8221; are able to process sequences in parallel, making processing much more efficient and faster.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-transformers-js-the-library-to-run-almost-all-models-available-on-hugging-face-in-the-browser\"><strong>Transformers.js \u2013 The Library to Run [Almost] All Models Available on Hugging Face in the Browser!<\/strong><\/h2>\n\n\n\n<p>Among the many new tools and software related to AI, you might have missed a solution that combines the &#8220;Transformers&#8221; and the web world: it is the Transformers.js library!<\/p>\n\n\n\n<p>This library allows you to run artificial intelligence models available in the Python world <strong>directly in your browser<\/strong>, thus opening up new possibilities in the field of web development and beyond.<\/p>\n\n\n\n<p>With Transformers.js, you can easily incorporate powerful NLP models, such as <a href=\"https:\/\/medium.com\/@reyhaneh.esmailbeigi\/bert-gpt-and-bart-a-short-comparison-5d6a57175fca\" target=\"_blank\" aria-label=\"GPT and BERT (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">GPT and BERT<\/a>, but also Computer Vision tasks like image-to-text, depth-estimation, and much more, into your web applications, Node.js, or Electron!<\/p>\n\n\n\n<p>All without the need to rely on external servers or cloud services since everything is <strong>executed inside the browser<\/strong>.<\/p>\n\n\n\n<p>This feature, in addition to the obvious low infrastructure cost, introduces a complete level of privacy: sensitive data (such as health status or webcam images) may not leave the user&#8217;s device; indeed, after downloading the model, your web app will also work offline!<\/p>\n\n\n\n<p>But how can we start using Transformers.js in our <a href=\"https:\/\/www.codemotion.com\/magazine\/frontend\/javascript\/javascript-guide\/\" target=\"_blank\" aria-label=\"JavaScript  (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">JavaScript <\/a>projects? Keep reading to find out!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-now-let-s-experience-the-thrill-of-creating-a-true-web-app-based-on-ai\"><strong>Now Let&#8217;s Experience the Thrill of Creating a True Web App Based on AI\u2026<\/strong><\/h2>\n\n\n\n<p>Here&#8217;s the most exciting part: putting into practice what we&#8217;ve discussed and creating a real web app based on artificial intelligence using Transformers.js!<\/p>\n\n\n\n<p>In this tutorial, we will guide you step-by-step through the creation of a simple web application (an AI translator tool) that uses a &#8220;Transformers&#8221; based text generation model to translate sentences from Italian to English. You&#8217;ll see how easy it is to integrate Transformers.js into your project and start exploring the world of Artificial Intelligence in a creative and familiar way.<\/p>\n\n\n\n<p>Prepare your favorite code editor and let&#8217;s tackle this simple AI translator step by step\u2026 like in a cooking recipe!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-practical-recipe-for-an-ai-translator-integrated-into-a-web-page\"><strong>Practical Recipe for an AI Translator Integrated into a Web Page<\/strong><\/h2>\n\n\n\n<p>For example, we will develop a simple translator that will use an <a href=\"https:\/\/huggingface.co\/Xenova\/opus-mt-it-en\" target=\"_blank\" aria-label=\"AI model to translate from Italian to English (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">AI model to translate from Italian to English<\/a> with a click!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-requirements\"><strong>Requirements<\/strong><\/h3>\n\n\n\n<p>You don&#8217;t need to know about AI, <a aria-label=\"Python (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/languages\/python\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Python<\/a>, or data science, just get by with vanilla JavaScript, HTML5, and CSS: the recipe is designed to be clear and accessible!<\/p>\n\n\n\n<p>For example, we will not use any bundler but a simple<strong> <code>\/public<\/code><\/strong> folder to be served with your favorite web server.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-ingredients\"><strong>Ingredients<\/strong><\/h3>\n\n\n\n<p>For our web app, we will need three main ingredients:<\/p>\n\n\n\n<p><strong>A minimalist UI:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-media-text is-stacked-on-mobile\"><figure class=\"wp-block-media-text__media\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-1024x576.png\" alt=\"simple AI translator\" class=\"wp-image-27413 size-full\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-1024x576.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-300x169.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-768x432.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-1536x864.png 1536w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-896x504.png 896w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54-400x225.png 400w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Screenshot_2024-04-29_11-16-54.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><div class=\"wp-block-media-text__content\">\n<ul class=\"wp-block-list\">\n<li>A minimalist graphical interface for translation with an AI model<\/li>\n\n\n\n<li>A textarea where the user will write the text to be translated<\/li>\n\n\n\n<li>A button to start the translation<\/li>\n\n\n\n<li>A textarea to display the translated output<\/li>\n<\/ul>\n<\/div><\/div>\n\n\n\n<p>A <strong>web worker<\/strong> (loaded as a module): will contain our AI model and allow us to query it without blocking the user interface of the main thread.<\/p>\n\n\n\n<p>A simple <strong>application logic<\/strong>: will be responsible for tying together the UI, the web worker, and the translation process.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-ai-translator-procedure\"><strong>AI translator &#8211; Procedure<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-preparing-the-ui\"><strong>Preparing the UI<\/strong><\/h3>\n\n\n\n<p>Let&#8217;s create a simple HTML page with textareas for input and output, along with a button to start the translation.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span> <span class=\"hljs-attr\">lang<\/span>=<span class=\"hljs-string\">\"en\"<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charset<\/span>=<span class=\"hljs-string\">\"UTF-8\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"viewport\"<\/span> <span class=\"hljs-attr\">content<\/span>=<span class=\"hljs-string\">\"width=device-width, initial-scale=1.0\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Web based AI Translator<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\".\/style.css\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"module\"<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\".\/app.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"translation-form\"<\/span>&gt;<\/span>\n            <span class=\"hljs-comment\">&lt;!-- input to translate --&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">textarea<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"italian-text\"<\/span> <span class=\"hljs-attr\">rows<\/span>=<span class=\"hljs-string\">\"6\"<\/span> <span class=\"hljs-attr\">spellcheck<\/span>=<span class=\"hljs-string\">\"false\"<\/span> <span class=\"hljs-attr\">required<\/span> <span class=\"hljs-attr\">disabled<\/span> <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"Italian text\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">textarea<\/span>&gt;<\/span>\n            <span class=\"hljs-comment\">&lt;!-- button we will attach the event to translate --&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"translate-button\"<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">disabled<\/span>&gt;<\/span>Loading model...<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n            <span class=\"hljs-comment\">&lt;!-- translated output (read-only) --&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">textarea<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"english-text\"<\/span> <span class=\"hljs-attr\">rows<\/span>=<span class=\"hljs-string\">\"6\"<\/span> <span class=\"hljs-attr\">spellcheck<\/span>=<span class=\"hljs-string\">\"false\"<\/span> <span class=\"hljs-attr\">placeholder<\/span>=<span class=\"hljs-string\">\"English text\"<\/span> <span class=\"hljs-attr\">readonly<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">textarea<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-comment\">&lt;!-- include a progress bar to indicate when we are downloading the AI model (often &gt; 50Mb) --&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"progress-bar\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-preparing-the-user-experience\"><strong>Preparing the User Experience<\/strong><\/h3>\n\n\n\n<p>Now that we have our index.html ready, it&#8217;s time to sketch out our app.js!<\/p>\n\n\n\n<p>We will limit ourselves to <strong>defining two functions to enable and disable interac<\/strong>tion with the user interface (being careful to wait for the HTML page to load).<\/p>\n\n\n\n<p>\ud83d\udd2e We will need it later when we are waiting for the results of long processes performed by the Web Worker.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">document<\/span>.addEventListener(<span class=\"hljs-string\">\"DOMContentLoaded\"<\/span>, () =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> translateButton = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'translate-button'<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> italianTextarea = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'italian-text'<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> englishTextarea = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'english-text'<\/span>);\n    <span class=\"hljs-keyword\">const<\/span> progressBar = <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">'progress-bar'<\/span>);\n\n    <span class=\"hljs-keyword\">const<\/span> disableUI = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        italianTextarea.setAttribute(<span class=\"hljs-string\">'disabled'<\/span>, <span class=\"hljs-literal\">true<\/span>);\n        englishTextarea.setAttribute(<span class=\"hljs-string\">'disabled'<\/span>, <span class=\"hljs-literal\">true<\/span>);\n        translateButton.setAttribute(<span class=\"hljs-string\">'disabled'<\/span>, <span class=\"hljs-literal\">true<\/span>);\n        translateButton.innerText = <span class=\"hljs-string\">'Translating...'<\/span>\n    }\n\n    <span class=\"hljs-keyword\">const<\/span> enableUI = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        italianTextarea.removeAttribute(<span class=\"hljs-string\">'disabled'<\/span>);\n        englishTextarea.removeAttribute(<span class=\"hljs-string\">'disabled'<\/span>);\n        translateButton.removeAttribute(<span class=\"hljs-string\">'disabled'<\/span>);\n        translateButton.innerText = <span class=\"hljs-string\">'Translate'<\/span>\n    }\n    <span class=\"hljs-comment\">\/\/ More code follows...<\/span>\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-creating-a-web-worker-to-download-and-run-the-ai-model\"><strong>Creating a Web Worker to Download and Run the AI Model<\/strong><\/h3>\n\n\n\n<p>Since downloading the AI model files from Hugging Face can be lengthy and especially will be run by the user&#8217;s CPU, we must include a Web Worker in our project!<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Web Worker<\/span>\n<span class=\"hljs-keyword\">import<\/span> {\n     pipeline,\n     env\n } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"https:\/\/cdn.jsdelivr.net\/npm\/@xenova\/transformers@2.17.1\"<\/span>;\n\nenv.allowLocalModels = <span class=\"hljs-literal\">false<\/span>; <span class=\"hljs-comment\">\/\/ If using models from Huggingface, this must be set<\/span>\n\n<span class=\"hljs-keyword\">var<\/span> translator;\n<span class=\"hljs-keyword\">var<\/span> task;\n<span class=\"hljs-keyword\">var<\/span> model;\n\n<span class=\"hljs-keyword\">const<\/span> progressCallback = <span class=\"hljs-function\">(<span class=\"hljs-params\">data<\/span>) =&gt;<\/span> {\n    self.postMessage({\n        <span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-string\">'downloading'<\/span>,\n        <span class=\"hljs-attr\">result<\/span>: data\n    });\n}\n\n<span class=\"hljs-keyword\">const<\/span> updateCallback = <span class=\"hljs-function\">(<span class=\"hljs-params\">beams<\/span>) =&gt;<\/span> {\n    <span class=\"hljs-keyword\">const<\/span> decodedText = translator.tokenizer.decode(beams&#91;<span class=\"hljs-number\">0<\/span>].output_token_ids, {\n        <span class=\"hljs-attr\">skip_special_tokens<\/span>: <span class=\"hljs-literal\">true<\/span>,\n    })\n\n    self.postMessage({\n        <span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-string\">'update'<\/span>,\n        <span class=\"hljs-attr\">result<\/span>: decodedText\n    });\n}\n\n<span class=\"hljs-keyword\">const<\/span> resultCallback = <span class=\"hljs-function\">(<span class=\"hljs-params\">output<\/span>) =&gt;<\/span> {\n    self.postMessage({\n        <span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-string\">'result'<\/span>,\n        <span class=\"hljs-attr\">result<\/span>: output\n    })\n}\n\nself.addEventListener(<span class=\"hljs-string\">'message'<\/span>, <span class=\"hljs-keyword\">async<\/span> (event) =&gt; {\n    <span class=\"hljs-keyword\">const<\/span> message = event.data;\n\n    <span class=\"hljs-keyword\">if<\/span> (message.action == <span class=\"hljs-string\">'download'<\/span>) {\n        task = message.task;\n        model = message.model;\n\n        translator = <span class=\"hljs-keyword\">await<\/span> pipeline(task, model, {\n            <span class=\"hljs-attr\">progress_callback<\/span>: progressCallback\n        });\n\n        self.postMessage({\n            <span class=\"hljs-attr\">status<\/span>: <span class=\"hljs-string\">'ready'<\/span>,\n            <span class=\"hljs-attr\">task<\/span>: task,\n            <span class=\"hljs-attr\">model<\/span>: model\n        });\n\n    } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (message.action == <span class=\"hljs-string\">'translate'<\/span>) {\n        <span class=\"hljs-keyword\">const<\/span> output = <span class=\"hljs-keyword\">await<\/span> translator(message.input, {\n            <span class=\"hljs-comment\">\/\/ Secret ingredient<\/span>\n            ...message.generation,\n            <span class=\"hljs-attr\">callback_function<\/span>: updateCallback\n        });\n\n        resultCallback(output&#91;<span class=\"hljs-number\">0<\/span>].translation_text);\n    }\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-adding-the-web-worker-to-the-app\"><strong>Adding the Web Worker to the App<\/strong><\/h3>\n\n\n\n<p>Back in our app.js where:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We will load the worker.js file, taking care to pass the option type: &#8220;module&#8221; allowing us to load <strong>Translator.js as an ES6 module<\/strong> \ud83d\udc69\u200d\ud83c\udfa4<\/li>\n\n\n\n<li>We will define two functions to send two messages or actions to the web worker: download and translate<\/li>\n\n\n\n<li>We will define what to do when our actions produce their respective results: ready when the model is ready and result when the result of the model&#8217;s execution is ready (text translated in this case)<\/li>\n\n\n\n<li>We include the functions enableUI() and disableUI() to inform the user when the APP can interact and when not<\/li>\n\n\n\n<li><strong>Extra<\/strong>: the web worker also informs us of the progress in downloads and to make it clear that the APP is doing something by updating its property based on the percentage of download &#8211;progress-bar-percentage<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">var<\/span> aiWorker = <span class=\"hljs-keyword\">new<\/span> Worker(<span class=\"hljs-string\">'worker.js'<\/span>, { <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-string\">\"module\"<\/span> });\n\n<span class=\"hljs-keyword\">const<\/span> translate = <span class=\"hljs-function\">(<span class=\"hljs-params\">text<\/span>) =&gt;<\/span> {\n    disableUI(); <span class=\"hljs-comment\">\/\/ This will take some time...<\/span>\n    aiWorker.postMessage({\n        <span class=\"hljs-attr\">action<\/span>: <span class=\"hljs-string\">'translate'<\/span>,\n        <span class=\"hljs-attr\">input<\/span>: text\n    });\n}\n\n<span class=\"hljs-keyword\">const<\/span> download = <span class=\"hljs-function\">(<span class=\"hljs-params\">model<\/span>) =&gt;<\/span> {\n    disableUI(); <span class=\"hljs-comment\">\/\/ This will take some time...<\/span>\n    aiWorker.postMessage({\n        <span class=\"hljs-attr\">action<\/span>: <span class=\"hljs-string\">'download'<\/span>,\n        <span class=\"hljs-attr\">task<\/span>: <span class=\"hljs-string\">'translation'<\/span>,\n        <span class=\"hljs-attr\">model<\/span>: model\n    });\n}\n\naiWorker.addEventListener(<span class=\"hljs-string\">'message'<\/span>, (event) =&gt; {\n\n     <span class=\"hljs-keyword\">const<\/span> { status, result } = event.data;\n\n     <span class=\"hljs-comment\">\/\/ Web Worker is informing us that...<\/span>\n     \n     <span class=\"hljs-keyword\">if<\/span> (status == <span class=\"hljs-string\">'downloading'<\/span>) {\n         <span class=\"hljs-keyword\">if<\/span> (result.status == <span class=\"hljs-string\">'progress'<\/span>) {\n             <span class=\"hljs-comment\">\/\/ animated progress bar for download<\/span>\n             progressBar.style.setProperty(<span class=\"hljs-string\">\"--progress-bar-percentage\"<\/span>, result.progress + <span class=\"hljs-string\">\"%\"<\/span>);\n         }\n\n     }  <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (status == <span class=\"hljs-string\">'ready'<\/span>) {\n         translateButton.addEventListener(<span class=\"hljs-string\">'click'<\/span>, () =&gt; {\n             translate(italianTextarea.value);\n         })\n\n         enableUI();\n     } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (status == <span class=\"hljs-string\">'update'<\/span>) {\n         <span class=\"hljs-comment\">\/\/ secret ingredient<\/span>\n         englishTextarea.value = result;\n     } <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (status == <span class=\"hljs-string\">'result'<\/span>) {\n         englishTextarea.value = result;\n         enableUI();\n         \n     }\n })\n\n download(<span class=\"hljs-string\">'Xenova\/opus-mt-it-en'<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-secret-ingredient\"><strong>The Secret Ingredient<\/strong><\/h3>\n\n\n\n<p>In the Web Worker and App comments, there are two points indicated as the <code>secret ingredient<\/code>\u2026 what is it?<\/p>\n\n\n\n<p>When we create our &#8220;pipeline&#8221; we can add a callback that informs us of the model&#8217;s progress by giving us the partial output of the answer. This is an essential ingredient because otherwise, the user would not see the output until the end of the execution which can take even minutes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"772\" height=\"388\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/Peek-2024-04-29-11-16.gif\" alt=\"Animation Showing the Words of Our Translator Coming Out One at a Time\" class=\"wp-image-27414\"\/><\/figure>\n\n\n\n<p class=\"has-text-align-left\">From the user experience point of view, it will be essential to find interesting and creative ways to give people the illusion that our Artificial Intelligence is alive and thinking! \ud83c\udfa9\u2728\ud83d\udc07<\/p>\n\n\n\n<p>By following these steps, you will be able to create a web app to translate text based on artificial intelligence!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-client-side-ai-model-conclusions\"><strong>Client-Side AI Model: Conclusions<\/strong><\/h2>\n\n\n\n<p>There are many limitations to using this technology at this time: the heavy model files and the slowness of a simple CPU are certainly the most obvious! Moreover, many models cannot be run in the browser context.<\/p>\n\n\n\n<p>However, I believe there are important aspects that make Transformers.js a great opportunity:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It is based on perhaps the most ubiquitous technology of the moment, the Transformers, and is also developed within Hugging Face\u2026 it&#8217;s really the JavaScript cousin of the Python library \ud83e\udd17<\/li>\n\n\n\n<li>You can make any model normally for Python compatible with a script (which transforms it into an optimized <a href=\"https:\/\/onnx.ai\/onnx\/intro\/\" target=\"_blank\" aria-label=\"ONNX  (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">ONNX <\/a>format): this means potentially having all models as soon as they come out!<\/li>\n\n\n\n<li>The parameters of the Python models are the same in Transformers.js so the documentation, once you&#8217;ve learned the key concepts, is also valid for JavaScript programmers<\/li>\n\n\n\n<li>Expands the ecosystem of AI models greatly, bringing them into PWAs, <a aria-label=\"Node.js servers (opens in a new tab)\" href=\"https:\/\/huggingface.co\/docs\/transformers.js\/tutorials\/node\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">Node.js servers<\/a>, and even <a aria-label=\"AI-based Desktop Applications (opens in a new tab)\" href=\"https:\/\/github.com\/xenova\/transformers.js\/tree\/main\/examples\/electron\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">AI-based Desktop Applications<\/a> with <a aria-label=\"ElectronJS (opens in a new tab)\" href=\"https:\/\/github.com\/xenova\/transformers.js\/tree\/main\/examples\/electron\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">ElectronJS<\/a>\u2026 all <a href=\"https:\/\/huggingface.co\/docs\/transformers.js\/index\" target=\"_blank\" aria-label=\"well-documented  (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">well-documented <\/a>even with use cases of <a aria-label=\"React and other frameworks (opens in a new tab)\" href=\"https:\/\/www.codemotion.com\/magazine\/languages\/a-complete-introduction-to-the-react-library\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">React and other frameworks<\/a><\/li>\n\n\n\n<li>Zero extra costs for external platforms and APIs<\/li>\n\n\n\n<li>Its author, <a href=\"https:\/\/twitter.com\/Xenovacom\" class=\"ek-link\">Xenova<\/a>, seems to have very clear ideas and from <a aria-label=\"this interview (opens in a new tab)\" href=\"https:\/\/youtu.be\/GVY__H89Ysk?si=ZuOP8SvM7ozFkTS-\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\">this interview<\/a> seems absolutely on the ball\u2026 and this seems to be a very promising aspect \ud83c\udf1f<\/li>\n\n\n\n<li>But above all, we are all waiting for the real superhero of the story: <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/WebGPU_API\" target=\"_blank\" aria-label=\"WebGPU (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">WebGPU<\/a><\/li>\n<\/ul>\n\n\n\n<p>But we will talk about this in future articles starting from the next in this series: Running a real Large Language Model (LLM) client-side in the browser!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Normally when we think of integrating an Artificial Intelligence model into a Web App, we immediately think of servers in Python or, even more often, cloud platform APIs. In this small guide, however, we want to explore a less trodden path: the possibility of including AI models directly in Web Apps for client-side use today&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/\">Read more<\/a><\/p>\n","protected":false},"author":255,"featured_media":27410,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[46],"tags":[9961,12065,12067],"collections":[11387],"class_list":{"0":"post-27570","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-ai-ml","8":"tag-javascript","9":"tag-llm","10":"tag-tutorial","11":"collections-top-of-the-week","12":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Easy client side AI translator with Transformers.js - Codemotion<\/title>\n<meta name=\"description\" content=\"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tutorial: Easy Client-side AI Translator With Transformers.js - Codemotion\" \/>\n<meta property=\"og:description\" content=\"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-07T14:12:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-07T16:34:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1216\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Massimo Avvisati\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@MassimoAvvisati\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Massimo Avvisati\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/\"},\"author\":{\"name\":\"Massimo Avvisati\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/7d033c17576f9bdfec9dab783e58976a\"},\"headline\":\"Tutorial: Easy Client-side AI Translator With Transformers.js &#8211; Codemotion\",\"datePublished\":\"2024-05-07T14:12:52+00:00\",\"dateModified\":\"2024-05-07T16:34:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/\"},\"wordCount\":1327,\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png\",\"keywords\":[\"JavaScript\",\"LLM\",\"tutorial\"],\"articleSection\":[\"AI\\\/ML\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/\",\"name\":\"Easy client side AI translator with Transformers.js - Codemotion\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png\",\"datePublished\":\"2024-05-07T14:12:52+00:00\",\"dateModified\":\"2024-05-07T16:34:33+00:00\",\"description\":\"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png\",\"width\":1216,\"height\":640,\"caption\":\"a robot, digital painting, dark orange and brown palette on light grey background\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AI\\\/ML\",\"item\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/ai-ml\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Tutorial: Easy Client-side AI Translator With Transformers.js &#8211; Codemotion\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#website\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Codemotion.Italy\\\/\",\"https:\\\/\\\/x.com\\\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/#\\\/schema\\\/person\\\/7d033c17576f9bdfec9dab783e58976a\",\"name\":\"Massimo Avvisati\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/massimo-100x100.jpeg\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/massimo-100x100.jpeg\",\"contentUrl\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/wp-content\\\/uploads\\\/2024\\\/04\\\/massimo-100x100.jpeg\",\"caption\":\"Massimo Avvisati\"},\"description\":\"I am a full-stack developer, digital artist, maker, and educator with a passion for Artificial Intelligence. I create immersive installations and develop educational software, pushing the boundaries of technology. I believe in Free Software and Creative Commons licensing as a foundation for knowledge sharing. My goal is to craft unique and engaging educational experiences using cutting-edge technology, showcasing the potential of AI in education. Currently, my focus is on Educational Technology, where I strive to create innovative software and hardware tools that engage and inspire learners. I firmly believe in the power of Free Software and Creative Commons, utilizing these open platforms to ensure my work is accessible and reusable by others. I actively reject restrictive platforms that limit creativity and collaboration. By combining my artistic vision with cutting-edge technology, I aim to develop unique educational experiences that spark curiosity and foster a love of learning. Through my work, I strive to demonstrate the incredible potential of AI in education and the arts.\",\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/massimo-avvisati-7220312\\\/\",\"https:\\\/\\\/x.com\\\/MassimoAvvisati\"],\"knowsAbout\":[\"Javascript\",\"Node.js\",\"PHP\",\"AI\",\"Machine Learning\",\"Web Development\",\"Free Software\"],\"knowsLanguage\":[\"English\",\"Spanish\",\"Italian\"],\"jobTitle\":\"Head of EdTech R&D\",\"worksFor\":\"Codemotion spa\",\"url\":\"https:\\\/\\\/www.codemotion.com\\\/magazine\\\/author\\\/massimo-avvisati\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Easy client side AI translator with Transformers.js - Codemotion","description":"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/","og_locale":"en_US","og_type":"article","og_title":"Tutorial: Easy Client-side AI Translator With Transformers.js - Codemotion","og_description":"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline","og_url":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2024-05-07T14:12:52+00:00","article_modified_time":"2024-05-07T16:34:33+00:00","og_image":[{"width":1216,"height":640,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png","type":"image\/png"}],"author":"Massimo Avvisati","twitter_card":"summary_large_image","twitter_creator":"@MassimoAvvisati","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"Massimo Avvisati","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/"},"author":{"name":"Massimo Avvisati","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/7d033c17576f9bdfec9dab783e58976a"},"headline":"Tutorial: Easy Client-side AI Translator With Transformers.js &#8211; Codemotion","datePublished":"2024-05-07T14:12:52+00:00","dateModified":"2024-05-07T16:34:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/"},"wordCount":1327,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png","keywords":["JavaScript","LLM","tutorial"],"articleSection":["AI\/ML"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/","url":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/","name":"Easy client side AI translator with Transformers.js - Codemotion","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png","datePublished":"2024-05-07T14:12:52+00:00","dateModified":"2024-05-07T16:34:33+00:00","description":"An Introductory Guide to Transformers.js, the JavaScript Library that Allows Running AI Models Directly in the Browser and Offline","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png","width":1216,"height":640,"caption":"a robot, digital painting, dark orange and brown palette on light grey background"},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/tutorial-easy-client-side-ai-translator-with-transformers-js-codemotion\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"AI\/ML","item":"https:\/\/www.codemotion.com\/magazine\/ai-ml\/"},{"@type":"ListItem","position":3,"name":"Tutorial: Easy Client-side AI Translator With Transformers.js &#8211; Codemotion"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/7d033c17576f9bdfec9dab783e58976a","name":"Massimo Avvisati","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/massimo-100x100.jpeg","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/massimo-100x100.jpeg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/massimo-100x100.jpeg","caption":"Massimo Avvisati"},"description":"I am a full-stack developer, digital artist, maker, and educator with a passion for Artificial Intelligence. I create immersive installations and develop educational software, pushing the boundaries of technology. I believe in Free Software and Creative Commons licensing as a foundation for knowledge sharing. My goal is to craft unique and engaging educational experiences using cutting-edge technology, showcasing the potential of AI in education. Currently, my focus is on Educational Technology, where I strive to create innovative software and hardware tools that engage and inspire learners. I firmly believe in the power of Free Software and Creative Commons, utilizing these open platforms to ensure my work is accessible and reusable by others. I actively reject restrictive platforms that limit creativity and collaboration. By combining my artistic vision with cutting-edge technology, I aim to develop unique educational experiences that spark curiosity and foster a love of learning. Through my work, I strive to demonstrate the incredible potential of AI in education and the arts.","sameAs":["https:\/\/www.linkedin.com\/in\/massimo-avvisati-7220312\/","https:\/\/x.com\/MassimoAvvisati"],"knowsAbout":["Javascript","Node.js","PHP","AI","Machine Learning","Web Development","Free Software"],"knowsLanguage":["English","Spanish","Italian"],"jobTitle":"Head of EdTech R&D","worksFor":"Codemotion spa","url":"https:\/\/www.codemotion.com\/magazine\/author\/massimo-avvisati\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-600x400.png","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-600x600.png","author_info":{"display_name":"Massimo Avvisati","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/massimo-avvisati\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png",1216,640,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-150x150.png",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-300x158.png",300,158,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-768x404.png",768,404,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-1024x539.png",1024,539,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png",1216,640,false],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd.png",1216,640,false],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-100x100.png",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-180x128.png",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-896x504.png",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-400x225.png",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-600x400.png",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/04\/50c0c4f3-8c6e-4f8b-8f16-9503e08c7ccd-600x600.png",600,600,true]},"uagb_author_info":{"display_name":"Massimo Avvisati","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/massimo-avvisati\/"},"uagb_comment_info":0,"uagb_excerpt":"Normally when we think of integrating an Artificial Intelligence model into a Web App, we immediately think of servers in Python or, even more often, cloud platform APIs. In this small guide, however, we want to explore a less trodden path: the possibility of including AI models directly in Web Apps for client-side use today&#8230;&hellip;","lang":"en","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/27570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/255"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=27570"}],"version-history":[{"count":3,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/27570\/revisions"}],"predecessor-version":[{"id":27598,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/27570\/revisions\/27598"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/27410"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=27570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=27570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=27570"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=27570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}