nsfwjs.com
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... and it's getting more accurate all the time.
At a glance
- Category
- Development
- Language
- English
- Paid-content signal
- No paid content foundObserved
- Registered
- 2019
- Hosting
- NetlifyInferred
- HTTPS certificate trusted
- PassedObserved
- Last updated
Related questions
More questions →What Is Lerna and How Does It Manage JavaScript Monorepos?
Lerna is a build system for managing and publishing multiple JavaScript or TypeScript packages from a single repository. It fits teams that keep several interdependent packages together and need coordinated versioning, publishing, and task running. If you only have one package, or your packages never share code or releases, Lerna adds overhead without much benefit.
The core problem Lerna solves
A monorepo puts many packages in one repository. That makes sharing code easy, but it creates coordination work:
- Which packages changed since the last release?
- What version should each changed package get?
- In what order should packages be published so dependencies exist first?
- How do you run a build or test across all packages without doing it manually?
Lerna addresses these by understanding the dependency graph between your packages and acting on it.
How Lerna manages a monorepo
Versioning
Lerna tracks which packages changed and updates their versions together or independently. It supports two common modes:
- Fixed mode: all packages share one version number and are released together.
- Independent mode: each package gets its own version, so you can release only what changed.
The choice matters. Fixed mode is simpler and suits tightly coupled packages. Independent mode gives finer control but requires more discipline.
Publishing
When you publish, Lerna determines the correct order based on inter-package dependencies, so a package that depends on another is published after its dependency. It can also create git tags and update changelogs as part of the release.
Running tasks across packages
Lerna can run a command (build, test, lint) across multiple packages, and it can scope that to only the packages affected by recent changes. This is the part that saves the most time in large repos, because you avoid rebuilding everything on every change.
Lerna and Nx
Lerna is now part of the Nx ecosystem. The relationship matters when you choose tooling:
- Lerna handles the monorepo versioning and publishing workflow.
- Nx provides the broader task running, caching, and project graph capabilities.
In practice, Lerna can use Nx under the hood for task execution and caching. If you already use Nx, Lerna fits as the release layer. If you only need publishing and versioning, Lerna can stand alone.
Lerna vs. plain npm/yarn workspaces
| Concern | npm/yarn workspaces | Lerna |
|---|---|---|
| Linking local packages | Yes | Yes (builds on workspaces) |
| Coordinated versioning | No | Yes |
| Ordered publishing | No | Yes |
| Changelog generation | No | Yes |
| Running tasks across packages | Limited | Yes, with affected-package scoping |
Workspaces solve dependency linking. Lerna solves the release and task-orchestration layer on top. Many projects use both: workspaces for installation, Lerna for versioning and publishing.
When Lerna is the right choice
Consider Lerna when:
- You maintain multiple packages that depend on each other.
- You need repeatable, ordered releases rather than manual
npm publishper package. - You want to run builds or tests only for packages affected by a change.
- You are already in or moving toward the Nx ecosystem.
Look elsewhere when:
- You have a single package.
- Your packages are released independently by different teams with no shared release process.
- You only need local linking and never publish.
Where to start
Begin with the Lerna documentation at lerna.js.org. The typical first steps are initializing Lerna in an existing repository, defining your package locations, and choosing fixed or independent versioning before your first release. Getting the versioning mode right early avoids a painful migration later.
How Do You Use jsDelivr to Load npm and GitHub Files via CDN?
Use jsDelivr by building a URL in the form https://cdn.jsdelivr.net/npm/package@version/file for npm packages, or https://cdn.jsdelivr.net/gh/user/repo@version/file for GitHub repositories. Pin an exact version for production, point the path at a real file inside the package, and expect the CDN to serve it from its global network. This works for any file type the package publishes, not just JavaScript.
The npm URL pattern
The core pattern is:
https://cdn.jsdelivr.net/npm/<package>@<version>/<file path>
A concrete example from jsDelivr's own documentation loads jQuery 3.6.4:
https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
Break that down:
npmtells jsDelivr the source is the npm registry.jqueryis the package name.@3.6.4pins the version./dist/jquery.min.jsis the file path inside the published package.
The path must match what the package actually publishes. If you guess a path that doesn't exist, you get a 404 rather than a fallback.
Version pinning vs. ranges
jsDelivr accepts several version forms, and the choice matters for stability.
| Form | Example | Behavior | Use in production? |
|---|---|---|---|
| Exact version | [email protected] |
Always serves that release | Yes |
| Version range | [email protected] |
Serves the latest 3.6.x | Only if you accept patch drift |
| Major range | jquery@3 |
Serves the latest 3.x | Risky |
| Omitted | jquery |
Serves the latest release | No |
jsDelivr's documentation explicitly warns against omitting the version in production, because the "latest" pointer moves whenever a new release is published. A range like @3.6 is a middle ground: you get bug fixes without a major-version jump, but the exact bytes can change between deploys.
Finding the right file
Three conveniences help when you don't know the exact path.
Minified variants. Append .min to any JS or CSS file to get a minified version. If the package doesn't ship one, jsDelivr generates it:
https://cdn.jsdelivr.net/npm/[email protected]/src/core.min.js
Default entry file. Omit the file path to get the package's default file:
https://cdn.jsdelivr.net/npm/[email protected]
Directory listing. Add a trailing slash to browse what's available:
https://cdn.jsdelivr.net/npm/jquery/
For programmatic discovery, the jsDelivr data API exposes entry points, versions, and file lists. For example, https://data.jsdelivr.com/v1/packages/npm/[email protected]/entrypoints returns the suggested entry file per file type, which is useful when a package's main file isn't obvious.
Loading GitHub files
GitHub-hosted files follow the same logic with a gh prefix:
https://cdn.jsdelivr.net/gh/<user>/<repo>@<version>/<file path>
The version can be a tag, a branch name, or a commit hash. Tags and commit hashes are stable; branch names move as the branch advances, so treat them like unpinned versions. The file path is relative to the repository root, so you reference the source file as committed, not a build artifact unless the repo commits one.
Combining and minifying on demand
jsDelivr can merge multiple files into one request by listing them after a combine path, and it minifies files on request as described above. This is handy for pulling several small modules or stylesheets in a single HTTP request. The trade-off is that a combined URL is a single point of failure: if one listed file is missing or renamed, the whole request breaks, so re-check combined URLs after dependency upgrades.
Troubleshooting common failures
404 on a file that exists locally. The published package may exclude that path (many packages ship only dist/ or only src/). Check the directory listing or the data API's file list to see what's actually published.
Wrong file served after an upgrade. You're probably using a range or an omitted version. Pin the exact version to lock the bytes.
Stale content after a fix. CDN caches hold files for a period, and jsDelivr offers a purge cache tool for exactly this case. Purging is the documented remedy when you've republished a version and need the edge to fetch it again. Note that republishing the same version is generally discouraged; publishing a new version is cleaner.
A file that works in one form but not another. Minified generation and default-file resolution depend on the package's contents. If .min generation or the default entry behaves unexpectedly, fall back to the explicit file path.
A quick checklist before going live
- Pin exact versions for every production URL.
- Confirm each path against the directory listing or data API.
- Prefer
.minfor JS and CSS to cut transfer size. - Avoid branch names and omitted versions in production.
- Keep the purge cache tool bookmarked for republished assets.
Following these steps gives you a stable, cache-friendly way to serve npm and GitHub files without bundling them yourself.
Website Overview
An established domain and managed infrastructure suggest continuity of operations and may support dependable delivery, although neither guarantees service quality. Several search or sharing settings need attention. Together they may make snippets, preview images or preferred URLs less consistent across platforms.
Domain and Registration
Registered in 2019, this domain has about 7 years of history. That suggests continuity, although ownership and purpose may have changed. Transfer-protection status is present, helping reduce the risk of unauthorized domain transfers. The registrar is Gandi SAS, a widely used domain service provider. The domain uses the common .com extension, which is not an independent safety signal.
DNS and Email
Nameservers are provided by NS1, indicating managed DNS hosting. No CNAME was found; the observed records resolve directly to addresses. No MX record was found. A conventional explicit inbound-mail route is not configured. DNSSEC signatures were not detected, so this additional DNS authenticity protection is not confirmed. The lowest observed DNS TTL is 120 seconds.
TLS and Certificates
The public key uses EC with 256 bits. The server supplied a complete certificate chain. No organization name is present in the certificate; the available fields are consistent with domain validation. The certificate was issued by Let's Encrypt, commonly associated with automated certificate services. The certificate's total validity is about 89 days, consistent with a short renewal cycle.
HTTP and Browser Security
The response lacks these common security headers: CSP, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, clickjacking protection. No X-Powered-By header was found, reducing one common source of backend fingerprinting information. No obvious internal addresses or debug information were found in the headers. The Server header contains the custom value Netlify. No explicit CDN or WAF marker was found in the response headers.
Technology Stack Analysis
The public page identifies Netlify without precise versions, leaving fewer clues for version-specific scanning.
Search and Social Sharing
The meta description has 197 characters and may be shortened in search results. No homepage canonical URL was detected. If duplicate URLs exist, consolidation may be less explicit. No Open Graph metadata was detected, so social previews may depend on platform inference. The title has 7 characters, within a common display range. The observed directives allow indexing and link following.
Hosting and Email
Registration details
| Registrar | Gandi SAS |
|---|---|
| Registered | 2019-02-14 |
| Expires | 2027-02-14 |
| Domain status | client transfer prohibited |
| Nameservers | dns1.p07.nsone.net、dns2.p07.nsone.net、dns3.p07.nsone.net、dns4.p07.nsone.net |
| DNSSEC | unsigned |
DNS records
TLS and certificates
HTTP response headers
| Header | Value |
|---|---|
| content-type | text/html; charset=UTF-8 |
| cache-control | public, max-age=0, must-revalidate |
| server | Netlify |
| strict-transport-security | max-age=31536000 |
Identified technologies
Pages, Search and Sharing
| Meta description | 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... and it's getting more accurate all the time. |
|---|---|
| Canonical URL | Not detected |
| Language | English (default) |
| Twitter Card | Not detected |
Unknown
robots.txt (opens in a new tab)
HTTP 404No robots.txt found
Sitemaps
0No sitemaps found
User reviews (0)