Rapid Diffs guidelines
These guidelines apply to every change to Rapid Diffs. For the architecture and how to add features, see Rapid Diffs.
Before writing code, review the design principles.
Caching
Each <diff-file> fragment must produce identical HTML for every user viewing
the same diff so the server can cache and reuse the fragment.
- Diff file components like
DiffFileComponent, viewers, and headers must only depend on diff content: the content SHA, file paths, line content, line numbers, and viewer name. - Place user-specific data such as permissions, preferences, and avatar URLs in
data-app-dataon the root element, not inside individual diff files. - Do not include request-specific data such as CSRF tokens or session state in diff file HTML.
- If a feature requires per-user content inside a diff file, such as discussion threads, load the content on the client after mount.
- When adding a property to a
ViewComponent, check whether the value changes per user. If the value changes, the property does not belong in the diff file template.
Client-server separation
- Render a feature on the server if the feature produces the same HTML for every user viewing the same diff. For example, syntax-highlighted code lines, hunk headers, and file headers are server-rendered. Handle a feature on the client through an adapter if the feature reacts to user input or varies per user. For example, inline discussions, file collapse toggle, options menu, and line permalink rewriting are client-side.
- Place global configuration in
data-app-data, per-file metadata indata-file-data, and small element-specific values in individualdata-*attributes. See Data flow to the client for the full reference. - Do not add latency between navigation and the first visible diff. If a change adds cost to the critical path, defer or eliminate the cost.
HTML and styling
- Do not use Tailwind utility classes inside diff file templates. A single diff
line with Tailwind classes can be 3-5x larger than one using a short
rd-class name. Over thousands of lines, this difference is significant. - Do not embed JSON blobs inside diff file bodies. Use
data-file-dataon the<diff-file>element, which is parsed once, anddata-*attributes on specific elements for small values. - Avoid deeply nested wrapper elements. Each extra
<div>multiplied across thousands of lines adds measurable overhead to parse time and memory. - Prefix all CSS classes with
rd-to avoid conflicts with legacy styles. - Avoid inline styles. Define styles in SCSS page bundles.
- Avoid deeply nested selectors. Prefer single-level class definitions.
- Use CSS variables for page-specific offsets like sticky headers and sidebar widths. Define them in page bundles, not in component styles.
Adapters and runtime
- Do not attach listeners to individual elements. Use delegated
clickshandlers or adapter lifecycle events. - Defer non-essential work to after the critical rendering path. Use
VISIBLE/INVISIBLEhandlers for work that applies once the file is visible. - Mount complex components on first user interaction, not ahead of time.
- Store intermediate state in
this.sink, not in closures. Closures that capture large DOM references cause memory leaks. - Clean up all event listeners and DOM references in
onUnmounted. If you store a DOM reference outside the adapter, such as in a Pinia store or a Vue component, clear the reference inonUnmountedas well. Failing to do so keeps the detached DOM tree in memory.
[MOUNTED](onUnmounted) {
const handler = () => { /* ... */ };
this.diffElement.addEventListener('input', handler);
onUnmounted(() => {
this.diffElement.removeEventListener('input', handler);
});
},Accessibility
Rapid Diffs must conform to level AA of the WCAG 2.1 and ATAG 2.0 guidelines.
- Provide text alternatives for non-text diff content such as images.
- Make all interactive elements operable by keyboard. File toggles, expand controls, discussion threads, and option menus must not require a mouse.
- Use semantic HTML and proper heading hierarchy so assistive technology users can navigate between files, hunks, and discussions.
- Preserve user preferences like view mode, whitespace settings, and file browser visibility across sessions.
- Follow the Pajamas accessibility developer checklist.