trmnlc/CLAUDE.md
Kate Meerburg 6188ecebb9 Add CLAUDE.md with project overview and architecture guide
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-24 21:01:21 +02:00

2.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

TRMNLc is a self-hosted server that serves rendered calendar displays to TRMNL e-ink devices. It fetches ICS calendar feeds, renders them as HTML using React SSR, screenshots the HTML with Puppeteer (Firefox), dithers the image with ImageMagick for e-ink display, and serves it via the TRMNL device API.

The UI is in Dutch (e.g., "VRIJ" = free, "BEZET" = busy, "VOLGENDE" = next, "DAARNA" = after that).

Running

# Install dependencies
bun install

# Run the server (requires Firefox and ImageMagick in PATH)
FIREFOX=/path/to/firefox CONFIG_FILE=config.json COLORMAP=./colormap.png bun run src/web.ts

The server runs on port 2300 by default (BUN_PORT env var). No test suite exists.

Architecture

The request flow for /api/display:

  1. src/web.ts — Bun HTTP server. Reads CONFIG_FILE JSON mapping device MAC addresses to ICS URLs + device model. Handles /api/setup, /api/display (returns rendered PNG), /api/display/html (returns raw HTML), and /api/render/:id/:ignore (serves cached PNGs).

  2. src/xlcalendar.tsxICSRenderable class. Fetches ICS feeds via node-ical, expands recurring events, processes them into current/next/secondary slots, and renders a React component to HTML via renderToString. Computes a content hash and calculates the next refresh time based on upcoming events.

  3. src/template.ts — Wraps plugin HTML output in a full HTML page with TRMNL's CSS/JS framework. Defines the Renderable interface and RenderMode type (full, half_horizontal, half_vertical, quadrant).

  4. src/render.ts — Uses Puppeteer (Firefox) to screenshot the rendered HTML, then pipes through ImageMagick (magick) to dither to a 2-bit grayscale PNG using the colormap.

  5. src/devices.ts — Fetches device model definitions (screen dimensions, CSS classes) from trmnl.com/api/models at startup.

Deployment

Deployed as a NixOS module via flake.nix / default.nix. The default.nix defines a systemd service with DynamicUser=true. The Nix derivation copies source directly (no build step — runs with bun run at runtime).

Formatting

Uses Prettier: single quotes, trailing commas (es5), 2-space indent, bracket same line.