NSFW JS Library


Single Licence: a single website (personal, client), or intranet site project - Details

Extended Licence: a website (commercial, personal, client), or internet site project - Details


Be the first to review this.

Save for later

Save this link to facebook.

Get Social

Hit like and share it with others.





Compatible Browsers



Well Documentation





Seller Store



Contact Me







Rated Points

demo example

Client-side indecent content checking

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.

Table of Contents

QUICK: How to use the module
Library API
load the model
classify an image

Host your own model

Run the Examples
Tensorflow.js in the browser
React Native
Node JS App
NSFW Filter(Browser Extension)

Open Source

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
With async/await support:
import * as nsfwjs from ‘nsfwjs’

const img = document.getElementById(‘img’)

// Load model from my S3.
// See the section hosting the model files on your site.
const model = await nsfwjs.load()

// Classify the image
const predictions = await model.classify(img)
console.log(‘Predictions: ‘, predictions)
Without async/await support:
import * as nsfwjs from ‘nsfwjs’

const img = document.getElementById(‘img’)

// Load model from my S3.
// See the section hosting the model files on your site.
.then(function (model) {
// Classify the image
return model.classify(img)
.then(function (predictions) {
console.log(‘Predictions: ‘, predictions)
Library API
load the model
Before you can classify any image, you’ll need to load the model. You should use the optional first parameter and load the model from your website, as explained in the install directions.
Model example – 224×224
const model = nsfwjs.load(‘/path/to/model/directory/’)
If you’re using a model that needs an image of dimension other than 224×224, you can pass the size in the options parameter.
Model example – 299×299
const model = nsfwjs.load(‘/path/to/different/model/’, { size: 299 })
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 example – Graph
const model = nsfwjs.load(‘/path/to/different/model/’, { type: ‘graph’ })
If you’re using in the browser and you’d like to subsequently load from indexed db or local storage you can save the underlying model using the appropriate scheme and load from there.
const initialLoad = await nsfwjs.load(‘/path/to/different/model’)
await initialLoad.model.save(‘indexeddb://model’)
const model = await nsfwjs.load(‘indexeddb://model’)
optional URL to the model.json folder.
optional object with size property that your model expects.
Ready to use NSFWJS model object
classify an image
This function can take any browser-based image elements (,

Array of the same order as number of frames in GIF. Each index corresponding to that frame, an returns array of objects that contain className and probability; sorted by probability and limited by topk config parameter.
Tensorflow.js offers two flags, enableProdMode and enableDebugMode. If you’re going to use NSFWJS in production, be sure to enable prod mode before loading the NSFWJS model.
import * as tf from ‘@tensorflow/tfjs’
import * as nsfwjs from ‘nsfwjs’
let model = await nsfwjs.load(`${urlToNSFWJSModel}`)
NSFWJS is powered by TensorFlow.js as a peer dependency. If your project does not already have TFJS you’ll need to add it.
# peer dependency
$ yarn add @tensorflow/tfjs
# install NSFWJS
$ yarn add nsfwjs
For script tags add . Then simply access the nsfwjs global variable. This requires that you’ve already imported TensorFlow.js as well.
Host your own model
The magic that powers NSFWJS is the NSFW detection model. By default, this node module is pulling from my S3, but I make no guarantees that I’ll keep that download link available forever. It’s best for the longevity of your project that you download and host your own version of the model files. You can then pass the relative URL to your hosted files in the load function. If you can come up with a way to bundle the model into the NPM package, I’d love to see a PR to this repo!
Run the Examples
Tensorflow.js in the browser
The demo that powers https://nsfwjs.com/ is available in the nsfw_demo example folder.
To run the demo, run yarn prep which will copy the latest code into the demo. After that’s done, you can cd into the demo folder and run with yarn start.
A browserified version using nothing but promises and script tags is available in the minimal_demo folder.
Please do not use the script tags hosted in this demo as a CDN. This can and should be hosted in your project along side the model files.
React Native
The NSFWJS React Native app

Loads a local copy of the model to reduce network load and utilizes TFJS-React-Native. Blog Post
Node JS App
Using NPM, you can also use the model on the server side.
$ npm install nsfwjs
$ npm install @tensorflow/tfjs-node
const axios = require(‘axios’) //you can use any http client
const tf = require(‘@tensorflow/tfjs-node’)
const nsfw = require(‘nsfwjs’)
async function fn() {
const pic = await axios.get(`link-to-picture`, {
responseType: ‘arraybuffer’,
const model = await nsfw.load() // To load a local model, nsfw.load(‘file://./path/to/model/’)
// Image must be in tf.tensor3d format
// you can convert image to tf.tensor3d with tf.node.decodeImage(Uint8Array,channels)
const image = await tf.node.decodeImage(pic.data,3)
const predictions = await model.classify(image)
image.dispose() // Tensor memory must be managed explicitly (it is not sufficient to let a tf.Tensor go out of scope for its memory to be released).
Here is another full example of a multipart/form-data POST using Express, supposing you are using JPG format.
const express = require(‘express’)
const multer = require(‘multer’)
const jpeg = require(‘jpeg-js’)

const tf = require(‘@tensorflow/tfjs-node’)
const nsfw = require(‘nsfwjs’)

const app = express()
const upload = multer()

let _model

const convert = async (img) => {
// Decoded image in UInt8 Byte array
const image = await jpeg.decode(img, true)

const numChannels = 3
const numPixels = image.width * image.height
const values = new Int32Array(numPixels * numChannels)

for (let i = 0; i < numPixels; i++)
for (let c = 0; c < numChannels; ++c) values[i * numChannels + c] = image.data[i * 4 + c] return tf.tensor3d(values, [image.height, image.width, numChannels], ‘int32’) } app.post(‘/nsfw’, upload.single(‘image’), async (req, res) => {
if (!req.file) res.status(400).send(‘Missing image multipart/form-data’)
else {
const image = await convert(req.file.buffer)
const predictions = await _model.classify(image)

const load_model = async () => {
_model = await nsfw.load()

// Keep the model in memory, make sure it’s loaded only once
load_model().then(() => app.listen(8080))

// curl –request POST localhost:8080/nsfw –header ‘Content-Type: multipart/form-data’ –data-binary ‘image=@/full/path/to/picture.jpg’
You can also use lovell/sharp for preprocessing tasks and more file formats.
NSFW Filter
NSFW Filter is a web extension that uses NSFWJS for filtering out NSFW images from your browser.
It is currently available for Chrome and Firefox and is completely open-source.
Check out the project here.
Learn TensorFlow.js
Learn how to write your own library like NSFWJS with my O’Reilly book “Learning TensorFlow.js” available on O’Reilly and Amazon.

An FAQ page is available.
More about NSFWJS and TensorFlow.js – https://youtu.be/uzQwmZwy3yw
The model was trained in Keras over several days and 60+ Gigs of data. Be sure to check out the model code which was trained on data provided by Alexander Kim’s nsfw_data_scraper.
Open Source
NSFWJS, as open source, is free to use and always will be ❤️. It’s MIT licensed, and we’ll always do our best to help and quickly answer issues. If you’d like to get a hold of us, join our community slack.
Infinite Red offers premium training and support. Email us at [email protected] to get in touch.
Thanks goes to these wonderful people (emoji key):

Gant Laborde? ? ? ? ? ? ? ⚠️
Jamon Holmgren? ? ? ?
Jeff Studenski?
Frank von Hoven III? ?
Sandesh Soni?
Sean Nam?
Gilbert Emerson?
Oleksandr Kozlov? ⚠️ ?
Morgan? ?
Michel Hua? ?
Kevin VanGelder? ?
Jesse Nicholson? ?
Cameron Burkholder?
Yegor <3? ⚠️
Navendu Pottekkat?
Vladislav? ?
kateinkim? ?
Rohan Mukherjee? ? ? ?
This project follows the all-contributors specification. Contributions of any kind welcome!

Comments and Discussions

  • webdev says:

    Pretty Cool

  • Reviews

    Copyrights © 2024-2025 All Rights Reserved