mrkeyoor.com_
Sat 08 Aug 21:58 UTC
npmUtilsupdated 08 Aug 2026

valid-url

valid-url is a tiny CommonJS module with four string-checking functions. isUri accepts any syntactically plausible RFC 3986 scheme, while isHttpUri, isHttpsUri, and isWebUri narrow that to absolute web addresses. A successful call returns the original string and a failed call returns undefined. It performs no network request, DNS lookup, normalization, or reachability check. The implementation was translated from an old Perl module and is best understood as a lightweight legacy input filter, not a modern URL parser or a security control.

Verdict

Keep it only when compatibility with an existing CommonJS call site matters. New code should normally use the built-in URL class or a maintained validator, especially when the address comes from an untrusted user.

API stability5/5The public surface is only isUri, isHttpUri, isHttpsUri, and isWebUri, plus snake_case aliases, and the 1.0.9 tarball still matches the README's original call shape. That surface has effectively been frozen for more than a decade. The high score reflects compatibility, not modern design: callers must preserve the unusual string-or-undefined result and CommonJS loading model.
Docs3/5The README documents all four methods, their success and failure contract, the absolute-URL requirement, and the important fact that no accessibility check occurs. It also includes the core examples. It does not document TypeScript, ESM, internationalized domains, host-validation limits, credential handling, or concrete security boundaries, and its linked historical Perl sources are no longer a useful onboarding path.
Maintenance1/5npm reports version 1.0.9 was published on 2013-07-31, GitHub reports the last repository push on 2021-09-17, and the repository still references Travis CI and a Tap 0.4 development dependency. The repository is not formally archived and the package is not marked deprecated, but there is no evidence of active releases or current-runtime testing, with 21 open issues and PRs remaining.
Ecosystem3/5The package recorded 4,741,806 downloads for the measured week and has no runtime dependency tree, so it remains widely present in Node installations and is cheap to retain transitively. Its integration surface is intentionally tiny, though: no TypeScript declarations, framework adapters, ESM build, browser-specific entry, or plugin ecosystem. Much of that download volume can reflect legacy dependency graphs rather than new adoption.

Use it if

  • You maintain CommonJS code that already depends on its return-string-or-undefined contract
  • You need a dependency-free check for absolute HTTP and HTTPS strings and can accept its deliberately practical, older rules
  • You need to distinguish generic URIs such as mailto and urn from web URLs with four very small functions
  • You support an old Node runtime where relying on the current WHATWG URL API is not an option
Skip it if

Setup reality

npm install valid-url adds no runtime dependencies and no configuration files, native builds, environment variables, or peer dependencies. The package is CommonJS only, so the documented shape is const validUrl = require('valid-url'); ESM projects may use a default import through Node interoperability, but named ESM imports are not an advertised interface. There are no bundled TypeScript declarations, so a typed project needs @types/valid-url or a small local declaration. The first surprise is the return type: every function returns the original string on success and undefined on failure, not a boolean. Coerce with Boolean(...) when an API expects true or false. The second is scope. isWebUri requires an absolute http:// or https:// address, so /account and example.com fail. isUri is broader and accepts schemes such as mailto, tel, urn, and javascript, so it is the wrong function for links that will be opened in a browser. Host validation is shallow, ports are not range-checked, Unicode is rejected, and credentials in an authority are accepted. If the value crosses a trust boundary, parse it with the platform URL class after this check, allowlist protocols and hosts, resolve DNS where relevant, and apply redirect checks separately. The test suite uses a very old Tap version and the repository has no current CI signal, which matters if you plan to fork or patch it.

Patterns

Accept an absolute HTTP or HTTPS URLcheck-web-url

const validUrl = require('valid-url');

const value = 'https://example.com/docs?q=node';
if (validUrl.isWebUri(value)) {
  console.log('accepted', value);
}

Success is the original string, not true; failure is undefined. Relative paths and bare domains are rejected.

Require HTTPS specificallyrequire-https

const validUrl = require('valid-url');

function requireHttps(value) {
  if (!validUrl.isHttpsUri(value)) {
    throw new TypeError('Expected an absolute HTTPS URL');
  }
  return value;
}

isHttpsUri rejects http:// values, but it does not check the certificate, host reachability, or redirect destination.

Check a non-web URIcheck-generic-uri

const validUrl = require('valid-url');

for (const value of ['mailto:team@example.com', 'tel:+1-816-555-1212']) {
  if (validUrl.isUri(value)) console.log(value);
}

isUri accepts any plausible scheme, including javascript:. Do not use it as an allowlist for clickable links.

Wrap the string result as a booleanreturn-boolean

const validUrl = require('valid-url');

function isAbsoluteWebUrl(value) {
  return typeof value === 'string' && Boolean(validUrl.isWebUri(value));
}

The typeof guard avoids passing arbitrary request-body values into an old string-oriented API.

Filter a list to web URLsfilter-url-list

const validUrl = require('valid-url');

const candidates = ['https://example.com', '/local', 'mailto:a@b.test'];
const webUrls = candidates.filter((value) => validUrl.isWebUri(value) !== undefined);

filter receives the original string as the truthy result. Use an explicit undefined comparison if that contract should be obvious to readers.

Validate a required form fieldvalidate-form-field

const validUrl = require('valid-url');

function validateHomepage(input) {
  const value = String(input ?? '').trim();
  if (!validUrl.isWebUri(value)) {
    return { ok: false, error: 'Enter a full http:// or https:// URL' };
  }
  return { ok: true, value };
}

Trimming is caller policy; the library rejects spaces rather than normalizing them.

Parse the accepted value with the platform URL APIparse-after-check

const validUrl = require('valid-url');

function parseWebUrl(value) {
  if (!validUrl.isWebUri(value)) throw new TypeError('Invalid web URL');
  const url = new URL(value);
  if (Number(url.port) > 65535) throw new TypeError('Invalid port');
  return url;
}

valid-url does not range-check ports or give you parsed components. In modern Node, URL alone is usually enough.

Reject embedded usernames and passwordsreject-url-credentials

const validUrl = require('valid-url');

function publicLink(value) {
  if (!validUrl.isWebUri(value)) return undefined;
  const url = new URL(value);
  if (url.username || url.password) return undefined;
  return url.href;
}

The package accepts user:password@authority syntax. Reject it explicitly before logging, storing, or displaying public links.

Allow only known HTTPS hostsallowlist-host

const validUrl = require('valid-url');

const allowed = new Set(['api.example.com', 'cdn.example.com']);
function isAllowedEndpoint(value) {
  if (!validUrl.isHttpsUri(value)) return false;
  const url = new URL(value);
  return allowed.has(url.hostname);
}

A syntax check does not prevent SSRF. For server-side requests, also handle DNS resolution, private IP ranges, redirects, and rebinding.

Reject a bad URL in Express middlewareexpress-request-validation

const validUrl = require('valid-url');

function requireCallbackUrl(req, res, next) {
  const value = req.body.callbackUrl;
  if (typeof value !== 'string' || !validUrl.isHttpsUri(value)) {
    return res.status(400).json({ error: 'callbackUrl must use https' });
  }
  req.callbackUrl = value;
  next();
}

Do not fetch the URL on this check alone. Apply destination and redirect policy before any outbound request.

Handle relative links separatelyaccept-relative-or-absolute

const validUrl = require('valid-url');

function resolveLink(value, base) {
  if (validUrl.isWebUri(value)) return new URL(value);
  if (value.startsWith('/') && !value.startsWith('//')) {
    return new URL(value, base);
  }
  throw new TypeError('Unsupported link');
}

All four package methods reject ordinary relative paths. Keep relative-link policy explicit instead of pretending they are malformed URLs.

Convert an internationalized hostname before checkingsupport-unicode-host

const validUrl = require('valid-url');
const { domainToASCII } = require('node:url');

const host = domainToASCII('例え.テスト');
const value = `https://${host}/`;
if (!host || !validUrl.isHttpsUri(value)) throw new TypeError('Invalid URL');

valid-url rejects non-ASCII characters. The native URL constructor already performs this conversion, so prefer it when legacy compatibility is not required.

Alternatives

PackageRegistryPick it when
validatornpmYou need maintained string validation with configurable URL rules and many adjacent validators
is-url-superbnpmYou want a small boolean URL predicate with a current package surface
url-regex-safenpmYou need safe URL matching inside larger text as well as whole-string checks