Web UI for Kindle clippings

This is about the third time I built a UI for viewing and organizing my Kindle clippings.

It seems that for me this is a sufficiently interesting, well defined, and practical problem that warrants coming back to. I initially wrote a CLI client for it, then a Flask app serving HTML templates, then this current iteration written in Go and React.

# Key Features

The fuzzy search functionality leverages Postgres’s trigram similarity matching. When a user types in the search box, the backend executes a query using the pg_trgm extension to find clips with similar text. The search results update in real-time as the user types.

# Label Management

Users can create and apply labels to organize their clips. The labels are stored in a separate table with a many-to-many relationship to clippings. The UI provides a dropdown component for label selection and creation.

# Label Filtering

Clips can be filtered by their applied labels. The filtering is handled on the backend with a JOIN query between the clippings and labels tables.

# Quick Actions

Each clip has quick actions for copying to clipboard, favoriting, and deletion. The clipboard functionality uses the browser’s native clipboard API.

# Infinite Scroll

To handle large collections efficiently, clips are loaded in batches as the user scrolls. The frontend tracks scroll position and requests the next batch of clips when nearing the bottom.

# Technical Implementation

# Backend

The backend is built with Go using the Mux router. Some interesting technical aspects:

  • Concurrent processing of uploaded Kindle clipping files using goroutines
  • Authentication middleware for Google Sign-in validation
  • Postgres trigram indexing for fuzzy search performance
  • Structured logging with Zap

The loader component demonstrates effective use of Go’s concurrency features. When processing the Kindle clippings file, it first splits the content into blocks and builds a map of authors and their works. Then, during database insertion, it spawns multiple goroutines using a worker pool pattern to concurrently handle the insertion of authors, documents, and their associated clippings. Each worker operates independently, protected by a WaitGroup to ensure all insertions complete before the process ends. This parallel processing significantly speeds up the import of large clipping files while maintaining data consistency through Postgres’s built-in conflict resolution.

# Frontend

The React frontend features:

  • Custom styled components for consistent UI
  • Context-based state management
  • Reusable components
  • Responsive design with mobile breakpoints
  • Debounced search input
  • Optimistic UI updates for label operations

The application demonstrates how Go’s concurrency features and React’s component model can be combined to create a responsive and user-friendly interface for managing Kindle highlights.

Written on April 5, 2023

If you notice anything wrong with this post (factual error, rude tone, bad grammar, typo, etc.), and you feel like giving feedback, please do so by contacting me at samubalogh@gmail.com. Thank you!