Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

What is Urly

Urly is a tiny Clojure library that unifies parsing of URIs, URLs and URL-like values like relative href values in real-world HTML.

Why Urly Was Necessary and in general do a great job of parsing valid (per RFCs) URIs and URLs. However, when working with real world HTML markup, it is common to come across href attribute values that are not valid URIs or URLs but are recognized and accepted by Web browsers. Normalization and resolution of such values cannot use or because both will throw illegal format exceptions.

Urly tries to make this less painful.

Supported Clojure versions

Urly is built from the ground up for Clojure 1.3+ and JDK 6+.



With Leiningen

[clojurewerkz/urly "1.0.0"]


The central concept in Urly is the UrlLike class. It unifies and as much as practical and also supports relative href attributes values like "/search?q=Clojure". UrlLike instances are immutable and perform normalizations that are safe (for example, uses default pathname of "/" and lowercases protocol and hostnames but not pathnames).

UrlLike instances are immutable. To mutate them, use UrlLike#mutateProtocol, UrlLike#mutatePath and similar methods (see examples below).

Urly is built around Clojure protocols so most of functions are polymorphic and can take strings as well as instances of

  • clojurewerkz.urly.UrlLike

as their first argument.

Key Functions

  (:refer-clojure :exclude [resolve])
  (:use clojurewerkz.urly.core)
  (:import [ URI URL]))

;; Instantiate a UrlLike instance
(url-like (URL. ""))
(url-like (URI. ""))
(url-like "")

;; unline, valid Internet domain names like "" and ""
;; will be recognized as hostname, not paths
(url-like "")
(url-like "")

;; accessing parts of the URL

(let [u (url-like "")]
  (protocol-of u)  ;; => "http"
  (.getProtocol u) ;; => "http"
  (.getSchema u)   ;; => "http"
  (host-of u)      ;; => ""
  (.getHost u)     ;; => ""
  (.getHostname u) ;; => ""
  (port-of u)     ;; => -1
  (path-of u)     ;; => "/", path is normalized to be "/" if not specified
  (query-of u)    ;; => nil
  (fragment-of u) ;; => nil
  (tld-of u)      ;; => "org"
  ;; returns all of the above as an immutable Clojure map
  (as-map u))

;; absolute & relative URLs

(absolute? "/faq") ;; => false
(relative? "/faq") ;; => true

(absolute? ( "")) ;; => true
(relative? ( "")) ;; => false

;; resolving URIs

(resolve (URI. "") (URI. "/Protocols"))                   ;; => (URI. "")
(resolve (URI. "") "/Protocols")                          ;; => (URI. "")
(resolve (URI. "") (URL. "")) ;; => (URI. "")
(resolve ""        (URI. "/Protocols"))                   ;; => (URI. "")
(resolve ""        (URL. "")) ;; => (URI. "")

;; mutating URL parts

(let [u (url-like "")]
  ;; returns a UrlLike instance that represents ""
  (.mutatePath u "/Protocols")
  ;; returns a UrlLike instance that represents ""
  (.mutateProtocol u "https")
  ;; returns a UrlLike instance with query string URL-encoded using UTF-8 as encoding
  (encode-query (url-like " function%22~10"))
  ;; returns a UrlLike instance that represents ""
  (-> u (.mutateQuery "search=protocols")
  ;; the same via Clojure API
  (-> u (mutate-query "search=protocols")
  ;; returns a UrlLike instance with the same parts as u but no query string
  (.withoutQuery u)
  ;; returns a UrlLike instance with the same parts as u but no fragment (#hash)
  (.withoutFragment u)
  ;; returns a UrlLike instance that represents ""
  (-> u (mutate-query "x=0&y=0&q=%22PREDICATE+FUNCTION%22~10")
        (mutate-query-with (fn [^String s] (.toLowerCase s)))))

;; stripping of extra protocol prefixes (commonly found in URLs on the Web)

(eliminate-extra-protocol-prefixes "http://") ;; =>
(eliminate-extra-protocol-prefixes "https://") ;; =>

Documentation & Examples

Documentation site for Urly is coming in the future (sorry!). Please see our extensive test suite for more code examples.

Continuous Integration

Continuous Integration status

CI is hosted by

Urly Is a ClojureWerkz Project

Urly is part of the group of Clojure libraries known as ClojureWerkz, together with Monger, Neocons, Langohr, Elastisch, Quartzite, Welle and several others.


Urly uses Leiningen 2. Make sure you have it installed and then run tests against all supported Clojure versions using

lein with-profile dev javac
lein all test

Then create a branch and make your changes on it. Once you are done with your changes and all tests pass, submit a pull request on Github.


Copyright (C) 2011-2012 Michael S. Klishin

Distributed under the Eclipse Public License, the same as Clojure.

Bitdeli Badge


A tiny Clojure library that parses and attempts to unify URIs, URLs and relative values found in real world HTML anchors






No packages published