# Repository: infinitered/nsfwjs
# Stars: 8849
## README.md
Client-side indecent content checking
[](#contributors)
[](https://dl.circleci.com/status-badge/redirect/gh/infinitered/nsfwjs/tree/master)
[](https://app.netlify.com/sites/nsfwjs/deploys)
A simple JavaScript library to help you quickly identify unseemly images; all in the client's browser. NSFWJS isn't perfect, but it's pretty accurate (~90% with small and ~93% with midsized model)... and it's getting more accurate all the time.
Why would this be useful? [Check out the announcement blog post](https://shift.infinite.red/avoid-nightmares-nsfw-js-ab7b176978b1).
## NOTE
If you're trying to access the Cloudfront hosted model and are running into an error, it's likely due to the fact that the model has been moved to a new location. Please take a look at our [Host your own model](#host-your-own-model) section. We will be returning the model after some hotlinkers have been dealt with.
## **Table of Contents**
- [QUICK: How to use the module](#quick-how-to-use-the-module)
- [Selective model bundles (tree-shaking)](#selective-model-bundles-tree-shaking)
- [Library API](#library-api)
- [`load` the model](#load-the-model)
- [Caching](#caching)
- [`classify` an image](#classify-an-image)
- [`dispose` a loaded model](#dispose-a-loaded-model)
- [Production](#production)
- [Backend selection](#backend-selection)
- [WASM backend (optional)](#wasm-backend-optional)
- [WebGPU backend (optional)](#webgpu-backend-optional)
- [Node.js backend](#nodejs-backend)
- [Install](#install)
- [Host your own model](#host-your-own-model)
- [Run the Examples](#run-the-examples)
- [Tensorflow.js in the browser](#tensorflowjs-in-the-browser)
- [Browserify](#browserify)
- [React Native](#react-native)
- [Node JS App](#node-js-app)
- [NSFW Filter](#nsfw-filter)
- [Learn TensorFlow.js](#learn-tensorflowjs)
- [More!](#more)
- [Open Source](#open-source)
- [Need the experts? Hire Infinite Red for your next project](#need-the-experts-hire-infinite-red-for-your-next-project)
- [Contributors](#contributors)
The library categorizes image probabilities in the following 5 classes:
- `Drawing` - safe for work drawings (including anime)
- `Hentai` - hentai and pornographic drawings
- `Neutral` - safe for work neutral images
- `Porn` - pornographic images, sexual acts
- `Sexy` - sexually explicit images, not pornography
> _The demo is a continuous deployment source - Give it a go: http://nsfwjs.com_
## QUICK: How to use the module
```js
import * as nsfwjs from "nsfwjs";
const img = document.getElementById("img");
// If you want to host models on your own or use different model from the ones available, see the section "Host your own model".
const model = await nsfwjs.load();
// Classify the image
const predictions = await model.classify(img);
console.log("Predictions: ", predictions);
```
### Selective model bundles (tree-shaking)
`nsfwjs` keeps the default behavior and includes built-in model definitions. For selective bundling, import from `nsfwjs/core` and pass only the models you want in `modelDefinitions`.
```js
import { load } from "nsfwjs/core";
import { MobileNetV2Model } from "nsfwjs/models/mobilenet_v2";
import { MobileNetV2MidModel } from "nsfwjs/models/mobilenet_v2_mid";
const model = await load("MobileNetV2", {
modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel],
});
```
If you pass an empty model registry, named bundled model loads will fail:
```js
await load("MobileNetV2", { modelDefinitions: [] }); // throws
```
## Library API
### `load` the model
Before you can classify any image, you'll need to load the model.
```js
const model = nsfwjs.load(); // Default: "MobileNetV2"
```
You can use the optional first parameter to specify which model you want to use from the three built-in bundled models. Defaults to: `"MobileNetV2"`.
For tree-shaken selective model bundling, use `nsfwjs/core` and pass `modelDefinitions` as shown above.
```js
const model = nsfwjs.load("MobileNetV2Mid"); // "MobileNetV2" | "MobileNetV2Mid" | "InceptionV3"
```
You can also use same parameter and load the model from your website/server, as explained in the [Host your own model](#host-your-own-model) section. Doing so could reduce the bundle size for loading the model by approximately 1.33 times (33%) since you can directly use the binary files instead of the base64 that are bundled with the package. i.e. The `"MobileNetV2"` model bundled into the package is 3.5MB instead of 2.6MB for hosted binary files. This would only make a difference if you are loading the model every time (without [Caching](#caching)) on the client-side browser since on the server-side, you'd only be loading the model once at the server start.
If you are hosting your own model via URL and want the smallest app bundle, import `load` from `nsfwjs/core` instead of `nsfwjs`. The core entrypoint does not include built-in model definitions by default, so bundlers do not pull those model assets into your app bundle.
```js
import { load } from "nsfwjs/core";
const model = await load("/path/to/mobilenet_v2/model.json");
```
Model MobileNetV2 - [224x224](https://github.com/infinitered/nsfwjs/blob/master/models/mobilenet_v2/)
```js
const model = nsfwjs.load("/path/to/mobilenet_v2/");
```
If you're using a model that needs an image of dimension other than 224x224, you can pass the size in the options parameter.
Model MobileNetV2Mid - [Graph](https://github.com/infinitered/nsfwjs/tree/master/models/mobilenet_v2_mid)
```js
/* You may need to load this model with graph type */
const model = nsfwjs.load("/path/to/mobilenet_v2_mid/", { type: 'graph' });
```
If you're using a graph model, you cannot use the infer method, and you'll need to tell model load that you're dealing with a graph model in options.
Model InceptionV3 - [299x299](https://github.com/infinitered/nsfwjs/tree/master/models/inception_v3)
```js
const model = nsfwjs.load("/path/to/inception_v3/", { size: 299 });
```
### Caching
If you're using in the browser and you'd like to subsequently load from indexed db or local storage (NOTE: model size may be too large for local storage!) you can save the underlying model using the appropriate scheme and load from there.
```js
const initialLoad = await nsfwjs.load(
"/path/to/different/model/" /*, { ...options }*/
);
await initialLoad.model.save("indexeddb://exampleModel");
const model = await nsfwjs.load("indexeddb://exampleModel" /*, { ...options }*/);
```
**Parameters**
Initial Load:
1. URL or path to folder containing `model.json`.
2. Optional object with size or type property that your model expects.
Subsequent Load:
1. IndexedDB path.
2. Optional object with size or type property that your model expects.
**Returns**
- Ready to use NSFWJS model object
**Troubleshooting**
- On the tab where the model is being loaded, inspect element and navigate to the the "Application" tab. On the left pane under the "Storage" section, there is a subsection named "IndexedDB". Here you can view if the model is being saved.
For a complete browser worker implementation (including backend initialization, IndexedDB-first load, and save-on-miss caching), see [`examples/nsfw_demo/src/nsfwjs.worker.ts`](./examples/nsfw_demo/src/nsfwjs.worker.ts).
### `classify` an image
This function can take any browser-based image elements (`
`, `