Skip to content

Making Your First Frontend Change

This guide walks you through the practical steps of making a frontend change to Open Library. It assumes you've read the Frontend overview and completed the Quick Start.

Before You Start

Before writing any code, take a few minutes to set yourself up for success:

  1. Find an issue. Look for issues labeled Good First Issue if you're new to the project. Avoid issues with labels like Needs: Staff Decision, Needs: Designs, or Needs: Lead — these haven't been vetted yet. Some issues have been previously discussed and declined — check for linked issues or PRs.

  2. Get assigned. Comment on the issue to express interest and wait for assignment. This prevents duplicate work.

  3. Understand the scope. Keep your change focused on what the issue asks for. If you notice other things to fix along the way, file separate issues for those. PRs that mix unrelated changes are harder to review and more likely to be sent back.

Build and Watch Commands

CSS and JavaScript changes require a rebuild. See the Quick Reference on the Frontend Reference page for all build, watch, and lint commands.

Template (HTML) changes auto-reload with no build step needed.

Finding the Right File

The most common question: "I want to change X — where do I look?"

"I want to change how a page looks"

  1. Find the template. Use the URL to trace the route. Routing lives in openlibrary/plugins — view classes point to templates in openlibrary/templates/. For example, /books/OL...M renders templates/type/edition/view.html.

  2. Find the CSS. Use your browser's developer tools to inspect the element and find the CSS class name. Then search for it in static/css/:

    sh
    # From the openlibrary repo root
    grep -r "book-card" static/css/
  3. Check for a design token. If you're changing a color, spacing, border radius, or font, the value likely comes from static/css/tokens/. Use a token instead of hardcoding values. If you need a new semantic token, add it to the appropriate token file and reference the primitive. See the Design Token Guide for details.

  4. Rebuild CSS and verify in the browser.

"I want to change text or layout on a page"

Templates are in openlibrary/templates/. The site wrapper (header, footer, navigation) is in templates/site/ and templates/lib/. Edit the .html file — changes auto-reload in your local instance. Templetor uses $variable for rendering values and $:variable for raw HTML. See the Template Rendering Guide for syntax details.

"I want to change a component's behavior"

Lit web components live in openlibrary/components/lit/. Each component is a single JS file registered in openlibrary/components/lit/index.js. See Building Components for details.

"I want to add JavaScript to an existing page"

JavaScript files live in openlibrary/plugins/openlibrary/js/. New JS is connected to templates through DOM-based loading in index.js — look for an element on the page, then dynamically import the JS file when that element exists. The Frontend Reference's JS tutorial walks through this pattern step by step.

For interactive UI that needs encapsulation, consider a Lit web component instead.

Testing Your Changes

After making your change, verify it works in the local Docker environment.

Finding the right page

Some common pages to test:

  • Book page: localhost:8080/books/OL1M (edition) or localhost:8080/works/OL1W (work)
  • Author page: localhost:8080/authors/OL1A
  • Search results: localhost:8080/search?q=test
  • Homepage: localhost:8080/
  • Lists: localhost:8080/people/openlibrary/lists

Testing components

Lit web components render on the pages that use them. To find where a component appears, search for its tag name (e.g., <ol-read-more>) in the templates:

sh
grep -r "ol-read-more" openlibrary/templates/

Vue components (merge UI, reading stats, library explorer) are accessed through specific URLs. If you're unsure where a component appears, ask in the issue or on Slack.

What to check

  • Both browsers: Test in Firefox and a Chromium-based browser (Chrome, Edge)
  • Mobile widths: Resize your browser or use device emulation to check responsive behavior
  • Without JavaScript: Disable JS in your browser briefly to confirm the page degrades gracefully — content should still be visible even if interactivity is lost
  • Page load: Watch for content that flashes or shifts as JavaScript loads (layout shift). Components should render at their final size from the start, or use a placeholder that matches the final dimensions

Before You Submit

Before opening a pull request, run through this checklist:

  • [ ] Lint passes: Run npm run lint for JS/CSS and make lint for Python
  • [ ] Tested in browser: Verify your change works locally in the browser at both desktop and mobile widths
  • [ ] Uses design tokens: No hardcoded colors, spacing, or radii — use tokens from static/css/tokens/
  • [ ] Follows conventions: BEM naming for CSS classes, ol- prefix for web components, semantic HTML
  • [ ] Screenshots included: Add before/after screenshots for any visual change. Screen recordings are even better for interactive changes.