If you want to add AI features such as sentiment analysis, recommendations or predictions to a Node.js app without switching to Python, this guide shows which approach fits, which JavaScript machine learning libraries are worth using, and working code you can run today.
Pick the right approach first
"Machine learning in Node.js" covers four quite different jobs:
| You want to… | Approach | Tools |
|---|---|---|
| Generate or summarise text, answer questions, act on requests | Call a hosted language model | The provider's official JavaScript SDK |
| Classify text or images with an existing model | Run a pretrained model inside Node.js | Transformers.js, ONNX Runtime |
| Train a small model on your own data | Train in JavaScript | TensorFlow.js |
| Train large models | Train in Python, serve the result to Node.js | PyTorch or TensorFlow, behind an API |
Most web features land in the first two rows. Training from scratch in JavaScript makes sense for small, specific problems, not for large models.
Node.js and CPU-heavy work
Node.js is fast at I/O because it runs your JavaScript on a single main thread and never waits on the network or disk. Machine learning is the opposite: running a model is CPU-heavy work, and while it runs on the main thread, every other request waits.
Two rules keep a Node.js app responsive:
- Use the native bindings. On the server, install
@tensorflow/tfjs-noderather than the pure-JavaScript@tensorflow/tfjs. It runs on TensorFlow's compiled C library and is much faster. - Move inference off the main thread once it takes more than a few milliseconds per request. Use
worker_threads(a pool library such as Piscina makes this easier), load the model once per worker rather than once per request, or run the model as a separate service.
Libraries worth using
TensorFlow.js
TensorFlow.js defines, trains and runs models in the browser or in Node.js. Install the Node version:
npm install @tensorflow/tfjs-node
This trains a one-neuron model to learn y = 2x - 1 and predicts the value for 5:
const tf = require('@tensorflow/tfjs-node');
async function main() {
const model = tf.sequential();
model.add(tf.layers.dense({ units: 1, inputShape: [1] }));
model.compile({ loss: 'meanSquaredError', optimizer: 'sgd' });
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
// One pass over four points isn't enough to learn anything; train for many epochs.
await model.fit(xs, ys, { epochs: 500, verbose: 0 });
model.predict(tf.tensor2d([5], [1, 1])).print(); // close to 9
}
main();
Earlier versions of this example called model.fit() with the default single epoch, which leaves the prediction far from 9.
Transformers.js
Transformers.js runs pretrained models from the Hugging Face Hub directly in JavaScript, in the browser or on the server. It's the quickest way to add sentiment analysis, text classification, translation or embeddings without training anything. It needs Node.js 20 or later and is an ES module:
npm install @huggingface/transformers
// sentiment.mjs
import { pipeline } from '@huggingface/transformers';
const classify = await pipeline('sentiment-analysis');
const results = await classify(['I love this movie!', 'It was terrible.']);
console.log(results);
// [{ label: 'POSITIVE', score: 0.99... }, { label: 'NEGATIVE', score: 0.99... }]
The first run downloads the model and caches it on disk, so the first request is slow. In production, set env.cacheDir to a folder you control and download the model when you build the container, not when the first user arrives.
natural
natural is a natural language toolkit for Node.js: tokenisers, stemmers, string distance, simple classifiers and a word-list sentiment analyser. It's lighter than a neural model and fine for rough scoring:
const natural = require('natural');
const tokenizer = new natural.WordTokenizer();
const analyzer = new natural.SentimentAnalyzer('English', natural.PorterStemmer, 'afinn');
console.log(analyzer.getSentiment(tokenizer.tokenize('I love this movie')));
// a positive number means positive sentiment
Brain.js
Brain.js is a small neural network library that's pleasant for learning and for simple problems. Its 2.0 release has been in beta for a long time, so check recent activity before building something long-lived on it. The classic XOR example:
const brain = require('brain.js');
const net = new brain.NeuralNetwork();
net.train([
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [0] },
]);
console.log(net.run([1, 0])); // close to 1
Libraries to skip or use with care
- Synaptic appeared in older guides, including an earlier version of this one. Its last release was in 2017, so don't start a new project with it.
- ml5.js is built on TensorFlow.js and aimed at the browser, especially creative coding. It's a good teaching tool rather than a server-side library.
Preparing your data
The model can only be as good as the data you train it on. Before you train, remove duplicates, handle missing values and check that every category you care about is represented. A model trained mostly on one kind of customer will be wrong about the others.
Useful JavaScript tools:
- Papa Parse reads and writes CSV, with
header: trueto get objects anddynamicTyping: trueto turn numbers into numbers. - Lodash for grouping, filtering and reshaping arrays of records.
- d3-array (part of D3) for summary statistics, binning and grouping.
Example: a simple recommendation engine
Recommendations don't always need a neural network. Item-based collaborative filtering finds items rated similarly by the same users and predicts what each user will like. This runs as-is with no dependencies:
// ratings[user][item], 0 = not rated yet
const ratings = [
[5, 0, 4, 1],
[4, 0, 5, 0],
[0, 3, 0, 2],
[1, 5, 0, 4],
];
function cosine(a, b) {
let dot = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] ** 2;
normB += b[i] ** 2;
}
return normA && normB ? dot / Math.sqrt(normA * normB) : 0;
}
const itemColumn = (item) => ratings.map((row) => row[item]);
function recommend(user, topN = 2) {
const itemCount = ratings[0].length;
const scores = [];
for (let item = 0; item < itemCount; item++) {
if (ratings[user][item] !== 0) continue; // already rated
let score = 0;
let weight = 0;
for (let other = 0; other < itemCount; other++) {
const rating = ratings[user][other];
if (rating === 0) continue;
const similarity = cosine(itemColumn(item), itemColumn(other));
score += similarity * rating;
weight += Math.abs(similarity);
}
if (weight > 0) scores.push({ item, predicted: score / weight });
}
return scores.sort((a, b) => b.predicted - a.predicted).slice(0, topN);
}
console.log(recommend(1)); // items user 1 hasn't rated, best first
To try it on real data, load the free MovieLens ratings datasets. Comparing every item with every other gets slow past a few thousand items. At that point, precompute the similarities in a nightly job, or move to matrix factorisation, trained in TensorFlow.js or in Python.
Testing and deploying
- Test the plumbing with ordinary unit tests: preprocessing, input validation and the shape of the output.
- Test the model on data it never saw during training. Hold back a test set, or use cross-validation on small datasets, and record the accuracy so you notice if a retrained model gets worse.
- Size the server for the model. Models live in memory. Measure memory use with the model loaded before choosing a container size.
- Monitor in production. Log predictions and, where you can, the real outcome. Data changes over time, and a model that was accurate at launch drifts. Plan when you'll retrain.
Where to go next
Start with the approach that needs the least training: a pretrained Transformers.js model or a hosted model API. Train your own only when nothing existing fits. If the feature needs to plan steps and call your own functions, read our guide to building an AI agent in Node.js. If the heavy lifting belongs in Python, see connecting a React frontend to a Python backend.
Written by
The people behind Wow Themes
The Wow Themes team builds and supports WordPress themes and plugins, plus Vue and React templates. On the blog we write about building, running and securing websites: WordPress and WooCommerce, JavaScript, performance and the tools we use day to day.




Comments
No comments yet.
Comments are closed on this post.