valid-url

Lightweight RFC 3986 URI and URL validation for Node.js, ported line-by-line from a battle-tested Perl module.

Library
npm
v1.0.9
212stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity0
Maintenance0
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture55
Code Quality60
Innovation45
Learning Curve75

valid-url is a small, dependency-free Node.js module that checks whether a string is a well-formed URI, HTTP URI, HTTPS URI, or web URI (HTTP or HTTPS). It implements the syntax rules from RFC 3986 directly, splitting a candidate string into scheme, authority, path, query, and fragment components and validating each piece according to the spec rather than relying on a loose regular expression.

The library was translated practically line-by-line from Richard Sonnen’s Perl module Data::Validate::URI, and it passes the original Perl test suite. Each exported function returns the untainted, normalized URI string on success and undefined on failure, so callers must explicitly check for a defined result rather than assuming truthiness alone indicates validity. It focuses narrowly on syntactic well-formedness — it does not attempt to resolve a hostname or check that a URL is reachable.

What You Get

  • isUri() - validates any RFC 3986-conformant URI (not limited to web addresses), returning the untainted URI string on success
  • isHttpUri() / isHttpsUri() - stricter validators that require a fully-qualified authority section and the matching scheme, with port-number handling built in
  • isWebUri() - a convenience function that accepts either HTTP or HTTPS, covering the common case of validating a web link
  • Zero runtime dependencies - the entire implementation is a single ~150-line file with no transitive packages to audit or update
  • Deterministic, spec-driven validation - matches RFC 3986 splitting rules rather than an ad-hoc regex, so edge cases like IPv6 host literals and percent-encoded paths are handled explicitly

Common Use Cases

  • Validating a URL field in a form or API request body before persisting it
  • Filtering user-submitted links (e.g. in comments, profiles, or bookmarks) to reject malformed or non-HTTP(S) input
  • Sanitizing redirect targets so only well-formed HTTP/HTTPS URIs are honored
  • Pre-validating URIs before handing them to a stricter downstream parser or fetch call

Under The Hood

Architecture The module is a single self-invoking function in index.js that attaches four public methods (plus camelCase aliases) directly onto module.exports. Internally, a private splitUri helper applies the canonical RFC 3986 Appendix B regular expression to break a candidate string into scheme, authority, path, query, and fragment groups; is_iri (backing isUri) validates the general grammar and character set, while is_http_iri (backing isHttpUri/isHttpsUri) layers stricter fully-qualified-authority and scheme checks on top of it, and is_web_iri (backing isWebUri) simply ORs the HTTP and HTTPS checks together. There is no class hierarchy, no configuration object, and no external state — every function is a pure transform from an input string to either a normalized URI string or undefined, so nothing else in a consuming application can break if this module changes internally.

Tech Stack The runtime code has no dependencies at all — it targets any Node.js version capable of running plain ES5 JavaScript. The only entries in package.json are devDependencies (tap for assertions and jshint for linting), invoked through a small Makefile wrapping npm test. There is no build step, bundler, or transpilation; the published package is exactly the source file.

Code Quality Tests live under test/, one file per exported function (is_uri.js, is_http_uri.js, is_https_uri.js, is_web_uri.js), written against the tap assertion library and directly mirroring the original Perl module’s test fixtures — both valid and deliberately malformed URIs are exercised. Error handling is implicit: invalid input simply yields undefined rather than throwing, which matches the “untaint on success, undefined on failure” contract described in the README, but does mean callers must remember to check for a defined result rather than truthiness. There is no TypeScript, and the code predates modern JS conventions (var, manual string concatenation), though it is consistent and readable throughout. A .jshintrc and Travis CI configuration show it was linted and tested in CI when active.

What Makes It Unique Rather than validating URLs with a single sweeping regular expression (the common approach in comparable packages), valid-url actually decomposes a string into its RFC 3986 grammar components and re-validates each part — scheme character set, authority-vs-path rules, percent-encoding completeness — before re-assembling and returning the normalized URI. That spec-fidelity, inherited directly from a well-established Perl validation module, is the library’s main differentiator over simpler regex-only alternatives, at the cost of being a much narrower tool than a full URL-parsing library.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search