diff --git a/openlibrary.go b/openlibrary.go
new file mode 100644
index 0000000000000000000000000000000000000000..580cc55501a546f70bd19af128670db50cbfff65
--- /dev/null
+++ b/openlibrary.go
@@ -0,0 +1,160 @@
+package liber
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"regexp"
+	"strings"
+)
+
+type openLibraryRefiner struct{}
+
+func (r *openLibraryRefiner) Name() string {
+	return "openlibrary"
+}
+
+type olSearchResults struct {
+	Docs []olSearchResult `json:"docs"`
+}
+
+type olSearchResult struct {
+	Title  string `json:"title"`
+	Author string `json:"author_name"`
+	Date   string `json:"first_publish_year"`
+	OLKey  string `json:"key"`
+}
+
+type olAuthor struct {
+	Name string `json:"name"`
+}
+
+type olPublisher olAuthor
+
+type olExcerpt struct {
+	Text string `json:"text"`
+}
+
+type olMetadata struct {
+	Key         string              `json:"key"`
+	Title       string              `json:"title"`
+	Identifiers map[string][]string `json:"identifiers"`
+	Authors     []*olAuthor         `json:"authors"`
+	Excerpts    []*olExcerpt        `json:"excerpts"`
+	Publishers  []*olPublisher      `json:"publishers"`
+	PublishDate string              `json:"publish_date"`
+	Cover       map[string]string   `json:"cover"`
+	Language    []string
+}
+
+var dateRx = regexp.MustCompile(`(\d{4})`)
+
+func (m *olMetadata) toMetadata() *Metadata {
+	out := &Metadata{
+		Title:    m.Title,
+		Language: m.Language,
+	}
+	for _, a := range m.Authors {
+		out.Creator = append(out.Creator, a.Name)
+	}
+	for _, p := range m.Publishers {
+		out.Publisher = append(out.Publisher, p.Name)
+	}
+	for _, attr := range []string{"isbn_10", "isbn_13"} {
+		if isbn, ok := m.Identifiers[attr]; ok {
+			out.ISBN = append(out.ISBN, isbn...)
+		}
+	}
+	if match := dateRx.FindString(m.PublishDate); match != "" {
+		out.Date = match
+	}
+	for _, e := range m.Excerpts {
+		out.Description = e.Text
+		break
+	}
+	return out
+}
+
+var olSemaphore = make(chan bool, 3)
+
+func openlibraryQuery(uri string, out interface{}) error {
+	olSemaphore <- true
+	defer func() {
+		<-olSemaphore
+	}()
+
+	resp, err := http.Get(uri)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		return fmt.Errorf("HTTP status %s", resp.Status)
+	}
+	if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Return book information given an ID.
+func (r *openLibraryRefiner) queryBibKeys(bibkeys []string) ([]*Metadata, error) {
+	values := make(url.Values)
+	values.Set("bibkeys", strings.Join(bibkeys, ","))
+	values.Set("jscmd", "data")
+	values.Set("format", "json")
+	uri := fmt.Sprintf("https://openlibrary.org/api/books?%s", values.Encode())
+
+	var result map[string]*olMetadata
+	if err := openlibraryQuery(uri, &result); err != nil {
+		return nil, err
+	}
+
+	var out []*Metadata
+	for _, m := range result {
+		out = append(out, m.toMetadata())
+	}
+	return out, nil
+}
+
+// Find a book given one or more ISBN numbers.
+func (r *openLibraryRefiner) queryISBN(isbn []string) ([]*Metadata, error) {
+	var bibkeys []string
+	for _, i := range isbn {
+		bibkeys = append(bibkeys, fmt.Sprintf("ISBN:%s", i))
+	}
+	return r.queryBibKeys(bibkeys)
+}
+
+// Find a book using title/author.
+func (r *openLibraryRefiner) queryTitleAuthor(m *Metadata) ([]*Metadata, error) {
+	values := make(url.Values)
+	values.Set("title", m.Title)
+	if len(m.Creator) > 0 {
+		values.Set("author", m.Creator[0])
+	}
+	uri := fmt.Sprintf("https://openlibrary.org/search.json?%s", values.Encode())
+
+	var result olSearchResults
+	if err := openlibraryQuery(uri, &result); err != nil {
+		return nil, err
+	}
+
+	var bibkeys []string
+	for _, doc := range result.Docs {
+		bibkeys = append(bibkeys, fmt.Sprintf("OLID:%s", doc.OLKey))
+	}
+	return r.queryBibKeys(bibkeys)
+}
+
+func (r *openLibraryRefiner) Lookup(m *Metadata) ([]*Metadata, error) {
+	if len(m.ISBN) > 0 {
+		return r.queryISBN(m.ISBN)
+	}
+	return r.queryTitleAuthor(m)
+}
+
+func (r *openLibraryRefiner) GetBookCover(m *Metadata) ([]byte, error) {
+	return nil, nil
+}
diff --git a/update.go b/update.go
index d16f7d782b1aff1effbfb6b685c90134621d58af..a00d30f6b7abea3c5c6ccb64720472e57e201fe0 100644
--- a/update.go
+++ b/update.go
@@ -306,6 +306,7 @@ func (db *Database) Update(dir string, chooser MetadataChooserFunc) {
 		// Check Google Books when the metadata is not
 		// sufficient to fully describe the book.
 		refiners: []MetadataRefiner{
+			//&openLibraryRefiner{},
 			&googleBooksRefiner{},
 		},
 	}