# Repository: infinitered/nsfwjs # Stars: 8849 ## README.md

NSFWJS Logo

Client-side indecent content checking

[![All Contributors](https://img.shields.io/badge/all_contributors-15-green.svg?style=flat-square)](#contributors) [![CircleCI](https://dl.circleci.com/status-badge/img/gh/infinitered/nsfwjs/tree/master.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/infinitered/nsfwjs/tree/master) [![Netlify Status](https://api.netlify.com/api/v1/badges/72d19dc0-d316-4f75-9904-a33d833ff628/deploy-status)](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).

demo example

## 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 (``, `