# Emotions AI

*A countrywide blackout, a doubled KFC order and a stray cat, turned into a real-time browser-based expression reader.*

- Year: 2024
- Built with: face-api.js, TensorFlow.js, JavaScript, Canvas, WebRTC
- Updated: 2026-09-07T20:55:52.721Z
- live: https://emotions-ai.abchaudary.me
- repo: https://github.com/abdullahchaudary/emotions

> Emotions AI reads facial expressions in the browser in real time with face-api.js, no server, built end to end during a national grid blackout.

## What it is

Emotions AI points a webcam at a face and labels the expression it finds, live, at frame rate: happy, sad, angry, fearful, disgusted, surprised, neutral. It runs entirely on the device. No frame is ever sent anywhere, because the model runs in the browser that opened the page.

## The day this got built (origin story)

A delivery of new speakers, extension cords and surge protectors arrived that January morning, the kind of order that makes a cold day feel handled. A childhood friend came by that afternoon, off work for the day, and we ordered KFC through the app and sat talking about nothing in particular. Then the power went out.

It didn't feel like a blackout. The backup supply was already running, the lights stayed on, and we kept talking. What gave it away was the food delivery app: the order had stopped updating, the connection had gone slow and unreliable, and the rider called instead of messaging, because the app itself couldn't be trusted to say where he was. He was outside with the order, and it was double what we'd ordered: a meal for six instead of two, from a kitchen that was clearly having the same day the network was. We ate the extra without arguing about it.

My friend works for the government's water and power department and had no idea anything was wrong until he checked his phone after we'd eaten. The reports on X were the same story everywhere: a fault in the national grid, a countrywide blackout, no further detail than that. He left as it started getting dark, and the internet, still technically up but barely usable, went from an inconvenience to the only entertainment left.

I started shutting down anything drawing power that didn't need to be on, more out of caution than necessity, and sat with what was left of the day. Getting the delivery, my friend visiting, the extra food, all of it had made me happy. The blackout had made me a little angry, a little sad. Sitting there naming what I'd felt that day is the exact moment the idea arrived: something that reads emotion the way I'd just been doing it to myself, but from a face instead of a memory.

With the internet too slow to be useful for anything else, I went looking for a model that could do it and found face-api.js, a face detection and expression library built on TensorFlow.js. 30 Seconds to Mars' "Alibi" was playing from an offline collection, the room was dark except for a lamp, and there was still a plate of leftover KFC on the coffee table. Then something started crackling on the table behind me: a stray cat had gotten into the house and was eating the leftovers. Fear first, then, once it left, something closer to disgust at the mess on the table. Both are labels the model I'd just started building would need to recognise: the day had produced a working sample of nearly every expression the app exists to detect, happy, angry, sad, fearful, disgusted, without my planning a single one of them.

By the time I'd cleaned up, I had a rough version working end to end. I spent the rest of the outage refining it: labels, an emoji per expression, the overlay drawn on the video feed. Power came back around 11pm, the reported cause a frequency drop in the national grid that stalled the whole system. When it did, I pushed everything live.

## Why face-api.js, not TensorFlow.js directly

face-api.js is built on TensorFlow.js, so both are true, but naming TensorFlow.js as the primary library would oversell what was written here. face-api.js supplies the face detector, the landmark model and the expression classifier as a single package with the pretrained weights already matched to them. The work in `script.js` is wiring: a `<video>` element, two stacked `<canvas>` overlays, and a render loop that draws the landmark mesh and the current label on top of the feed.

## The architecture is the absence of one

There is no `package.json` in this repository. No build step, no bundler, no framework, no server doing inference. `index.html` loads two scripts, `face-api.min.js` and `script.js`, and that is the entire application.

Twelve model files sit in the repo's own `models/` directory: the expression classifier, the 68-point face landmark detector, its tiny variant, and the detector weights. The browser downloads them once and runs the network locally. That detail is what makes the privacy claim checkable rather than promised. A page that sends frames to an API for classification and a page that classifies them on your machine look identical from the outside. Here you can open the network tab and watch it: weights come down, and nothing goes back up.

## What's still rough (known limitations)

There's no error handling for a denied camera permission, no fallback for a browser without `getUserMedia`, and the live page's own `<title>` still reads "Emotions AI | Tensorflow X Javascript X Camera = Coolness", the most 2023 sentence on this entire site. None of it has been cleaned up, on purpose: this is a single-evening build, not a maintained product, and tidying the title would erase the timestamp on the joke.

## Outcome

Created that January and still receiving pushes as late as September the following year, this is the longest-lived of [the five browser experiments](/projects) on this domain, outliving projects started both before and after it. The point was never really about emotion detection. It was that the same evening handed me the problem, the data to test it on and the time to build it, and software turned out to be a reasonable way to hold onto all three.

## Links

Live: [emotions-ai.abchaudary.me](https://emotions-ai.abchaudary.me). Source: [github.com/abdullahchaudary/emotions](https://github.com/abdullahchaudary/emotions).
