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
# Fuzzy Search
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.