@pierre/diffs is an open source diff and code rendering library. It's built on Shiki for syntax highlighting and theming, is super customizable, and comes packed with features. Made with love by The Pierre Computer Company.
Currently v1.0.2
Choose from stacked (unified) or split (side-by-side). Both use CSS Grid and Shadow DOM under the hood, meaning fewer DOM nodes and faster rendering.
11 unmodified lines12 ThemesType,13} from '../types';1415export function createSpanFromToken(token: ThemedToken) {16 ThemesType,17} from '../types';18 ThemesType,21 ThemesType,22} from '../types';2324export function createSpanFromToken(token: ThemedToken) {25 const element = document.createElement('span');26 const style = token.htmlStyle ?? getTokenStyleObject(token);27 element.style = stringifyTokenStyle(style);26 ThemesType,27} from '../types';2829export function createSpanFromToken(token: ThemedToken) {28 ThemesType,29} from '../types';3033 ThemesType,31 ThemesType,32} from '../types';3334export function createSpanFromToken(token: ThemedToken) {27 unmodified lines11 unmodified lines12 ThemesType,13} from '../types';1415export function createSpanFromToken(token: ThemedToken) {16 ThemesType,17} from '../types';18 ThemesType,19 ThemesType,20} from '../types';21 ThemesType,22} from '../types';2324export function createSpanFromToken(token: ThemedToken) {25 const element = document.createElement('span');26 const style = token.htmlStyle ?? getTokenStyleObject(token);27 element.style = stringifyTokenStyle(style);28 ThemesType,29} from '../types';3031 ThemesType,32} from '../types';3334export function createSpanFromToken(token: ThemedToken) {27 unmodified lines
We built @pierre/diffs on top of Shiki for syntax highlighting and general theming. Our components automatically adapt to blend in with your theme selection, including across color modes.
1use std::io;23fn main() {4use std::io;5use std::io;6use std::io;78use std::io;910use std::io;1112use std::io;1use std::io;23fn main() {4use std::io;5use std::io;6use std::io;78use std::io;910use std::io;1112use std::io;
Love the Pierre themes? Install our Pierre VS Code Theme pack with light and dark flavors.
Your diffs, your choice. Render changed lines with classic diff indicators (+/–), full-width background colors, or vertical bars. You can even highlight inline changes—character or word based—and toggle line wrapping, hide numbers, and more.
1const std = @import("std");2const std = @import("std");3const std = @import("std");4const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;5const ArrayList = std.ArrayList;10const std = @import("std");7const std = @import("std");12const std = @import("std");13const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;14const ArrayList = std.ArrayList;16const std = @import("std");12const std = @import("std");18const std = @import("std");19const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;1const std = @import("std");2const std = @import("std");3const std = @import("std");4const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;5const ArrayList = std.ArrayList;6const std = @import("std");7const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;8const ArrayList = std.ArrayList;910const std = @import("std");11const std = @import("std");12const std = @import("std");13const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;14const ArrayList = std.ArrayList;15const std = @import("std");16const std = @import("std");17const std = @import("std");18const std = @import("std");19const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;
@pierre/diffs adapts to any font, font-size, line-height, and even font-feature-settings you may have set. Configure font options with your preferred CSS method globally or on a per-component basis.
38 unmodified lines39 if !exists {40 return nil, false41 }42
43 if !exists {44 return nil, false45 }43 if !exists {44 if !exists {47 if !exists {45 if !exists {46 return nil, false47 }48
7 unmodified linesUse renderHeaderMetadata to inject custom content and components into the file header. Perfect for adding view toggles, theme switchers, copy buttons, or any other file-level actions while preserving the built-in header.
4 unmodified lines56 let apiBaseURL: URL7 let timeout: TimeInterval8 let maxRetries: Int1011 let apiBaseURL: URL1112 let apiBaseURL: URL13 let timeout: TimeInterval1617 let apiBaseURL: URL1617 let apiBaseURL: URL2019232829 let apiBaseURL: URL4 unmodified lines56 let apiBaseURL: URL7 let timeout: TimeInterval8 let maxRetries: Int91011 let apiBaseURL: URL1213 let apiBaseURL: URL14 let timeout: TimeInterval15 let maxRetries: Int1617 let apiBaseURL: URL1819 let apiBaseURL: URL202122 let apiBaseURL: URL232425 let apiBaseURL: URL26 let timeout: TimeInterval27 let maxRetries: Int2829 let apiBaseURL: URL
@pierre/diffs provide a flexible annotation framework for injecting additional content and context. Use it to render your own line comments, annotations from CI jobs, and other third-party content.
2 unmodified lines3from typing import Optional4
5SECRET_KEY = "your-secret-key"6
7from typing import Optional7from typing import Optional8from typing import Optional9
10from typing import Optional11from typing import Optional12
13SECRET_KEY = "your-secret-key"14
14from typing import Optional15from typing import Optional16from typing import Optional17
18SECRET_KEY = "your-secret-key"19
19from typing import Optional20from typing import Optional 21from typing import Optional22
Should we validate the role parameter? We could restrict it to a set of allowed values.
Good idea, maybe use a Literal type or an enum.
Agreed, we should also update verify_token to return the role.
Annotations can also be used to build interactive code review interfaces similar to AI-assisted coding tools like Cursor. Use it to track the state of each change, inject custom UI like accept/reject buttons, and provide immediate visual feedback.
4 unmodified lines5 <title>Welcome</title>6</head>7<body>8 <header>9 <title>Welcome</title>10</head>9 <title>Welcome</title>10</head>11<body> 12 <title>Welcome</title>13</head>14<body>15 <header>2 unmodified linesTurn on line selection with enableLineSelection: true. When enabled, clicking a line number will select that line. Click and drag to select multiple lines, or hold Shift and click to extend your selection. You can also control the selection programmatically. Also selections will elegantly manage the differences between split and unified views.
16 unmodified lines17 }1819 ~Vector() {20 delete[] data;21 }21 }2223 ~Vector() {24 delete[] data;26 }27 }2829 ~Vector() {30 delete[] data;31 }32 }3334 ~Vector() {32 }3334 ~Vector() {42 }4344 ~Vector() {45 delete[] data;10 unmodified lines16 unmodified lines17 }1819 ~Vector() {20 delete[] data;21 }2223 ~Vector() {24 delete[] data;25 }2627 }2829 ~Vector() {30 delete[] data;31 }32 }3334 ~Vector() {35 }3637 ~Vector() {38 delete[] data;39 }4041 void push_back(const T& value) {42 }4344 ~Vector() {45 delete[] data;10 unmodified lines
In addition to rendering standard Git diffs and patches, you can pass any two files in @pierre/diffs and get a diff between them. This is especially useful when comparing across generative snapshots where linear history isn't always available. Edit the css below to see the diff.
1.pizza {2 display: flex;3.pizza {3.pizza {Our team has decades of cumulative experience in open source, developer tools, and more. We’ve worked on projects like Coinbase, GitHub, Bootstrap, Twitter, Medium, and more. This stuff is our bread and butter, and we’re happy to share it with you.