npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-diffs

v1.0.3

Published

React Native diff view

Readme

React Native Diffs

Diff library for React Native, powered by MarkdownView.

Installation

npm install react-native-diffs react-native-nitro-modules

Usage

import { DiffsView } from 'react-native-diffs';

const diff = `\`\`\`diff
@@ -11,7 +11,7 @@ export default function Home() {
 <div>
-  <h2>Design Engineer</h2>
+  <h2>Designer</h2>
 </div>
\`\`\``;

export default function App() {
  return (
    <DiffsView
      content={diff}
      colorScheme="dark"
      style={{ flex: 1 }}
    />
  );
}

Diff formats

Content can be a fenced ```diff ``` or ```patch ``` code block, or a raw unified diff string — MarkdownView auto-detects and renders it as a styled diff view with hunk headers, line numbers, and inline change highlighting.

You can also include multiple fenced diff blocks in a single content string to render them all in one scrollable view.

Examples

Custom dark theme

import { DiffsView, type Theme } from 'react-native-diffs';

const theme: Theme = {
  fonts: {
    codeSize: 15,
  },
  colors: {
    body: '#E1E2E5',
    code: '#D4D4D8',
    codeBackground: '#18181B',
    highlight: '#60A5FA',
    emphasis: '#A1A1AA',
    selectionTint: '#34D399',
  },
  diff: {
    displayMode: 'unified',
    changeHighlightStyle: 'both',
    backgroundColor: '#000000',
    gutterBackground: '#0A0A0A',
    gutterText: '#52525B',
    addedLineBackground: '#22C55E33',
    removedLineBackground: '#DC262620',
    addedHighlightBackground: '#4ADE8066',
    removedHighlightBackground: '#DC262650',
    hunkHeaderBackground: '#27272A',
    hunkHeaderText: '#71717A',
    separatorColor: '#27272A',
    borderWidth: 0,
  },
};

<DiffsView
  content={diff}
  colorScheme="dark"
  showsBlockHeaders={false}
  theme={theme}
  style={{ flex: 1, backgroundColor: '#000000' }}
/>

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | content | string | Yes | Markdown or diff content to render | | colorScheme | string | Yes | Color scheme ("dark" or "light") | | contentInset | ContentInset | No | Scroll view content inset { top, bottom } | | showsBlockHeaders | boolean | No | Show code/diff block headers with copy button (default true) | | theme | Theme | No | Custom theme configuration | | customMenuItems | CustomMenuItem[] | No | Extra items appended to the text-selection menu on code/diff blocks | | onCustomMenuAction | (event: CustomMenuEvent) => void | No | Fires when a custom menu item is tapped. Must be wrapped as { f: handler } (see below) | | onLineSelection | (info?: LineSelectionInfo) => void | No | Enables line selection mode; fires continuously as the user drags. Wrap as { f: handler } | | onLineSelectionEnd | (info?: LineSelectionInfo) => void | No | Fires once when the selection gesture settles (tap release / drag release). Wrap as { f: handler }. Setting only this still enables line selection. |

Callback wrapping

Nitro view-prop callbacks cross the bridge as a reference-tracked wrapper, so functions must be passed as { f: handler } rather than bare functions:

<DiffsView
  onCustomMenuAction={{ f: (event) => console.log(event) }}
  onLineSelectionEnd={{ f: (info) => console.log(info) }}
/>

Custom menu items

Long-press a code or diff block to bring up the text-selection menu. Items in customMenuItems are appended after the system actions (Copy, Select All, Share). systemImage accepts any SF Symbol name.

<DiffsView
  content={content}
  customMenuItems={[
    { id: 'explain', title: 'Explain', systemImage: 'lightbulb' },
    { id: 'apply', title: 'Apply', systemImage: 'checkmark.circle' },
  ]}
  onCustomMenuAction={{
    f: ({ itemId, text, startLine, endLine }) => {
      console.log(itemId, text, startLine, endLine);
    },
  }}
/>

Line selection

Providing onLineSelection or onLineSelectionEnd switches code and diff blocks from text selection to line selection: tap to select a single line, or long-press-and-drag to select a range.

  • onLineSelection fires on every range change — use it for live visual feedback.
  • onLineSelectionEnd fires exactly once per interaction, when the user lifts their finger — use it for actions like showing a contextual button. You can set it on its own.

Customize the highlight with theme.colors.lineSelectionBackground.

<DiffsView
  content={content}
  theme={{ colors: { lineSelectionBackground: '#60A5FA33' } }}
  onLineSelectionEnd={{
    f: (info) => {
      if (!info) return;
      console.log(`lines ${info.startLine}-${info.endLine}`, info.contents);
    },
  }}
/>

Theming

Pass a theme prop to customize the appearance. All fields are optional — only override what you need. Colors are hex strings with optional alpha (e.g. "#FF0000" or "#FF000080"). Colors are rendered in the Display P3 color space for wider gamut on supported devices.

Theme Structure

ThemeFonts

| Property | Type | Description | |----------|------|-------------| | bodySize | number | Body text font size | | codeSize | number | Code block font size | | codeInlineSize | number | Inline code font size | | titleSize | number | Title font size | | largeTitleSize | number | Large title font size | | footnoteSize | number | Footnote font size |

ThemeColors

| Property | Type | Description | |----------|------|-------------| | body | string | Main text color | | highlight | string | Highlight/accent color | | emphasis | string | Emphasis color | | code | string | Code text color | | codeBackground | string | Code block background color | | selectionTint | string | Text selection tint color | | selectionBackground | string | Text selection fill. Defaults to selectionTint at 20% alpha | | lineSelectionBackground | string | Highlight color used in line selection mode |

ThemeSpacings

| Property | Type | Description | |----------|------|-------------| | final | number | Final spacing (default 16) | | general | number | General inter-block spacing (default 8) | | list | number | List item spacing (default 8) | | cell | number | Cell spacing (default 32) |

ThemeSizes

| Property | Type | Description | |----------|------|-------------| | bullet | number | Bullet point size (default 4) |

ThemeTable

| Property | Type | Description | |----------|------|-------------| | cornerRadius | number | Table corner radius (default 8) | | borderWidth | number | Table border width (default 1) | | borderColor | string | Border color | | headerBackgroundColor | string | Table header background | | cellBackgroundColor | string | Cell background | | stripeCellBackgroundColor | string | Alternating row background |

ThemeImage

| Property | Type | Description | |----------|------|-------------| | cornerRadius | number | Image corner radius (default 4) | | maxWidthFraction | number | Max width as fraction of container (default 1.0) | | placeholderColor | string | Loading placeholder color |

ThemeDiff

| Property | Type | Description | |----------|------|-------------| | displayMode | DiffDisplayMode | 'unified' or 'sideBySide' | | scrollBehavior | DiffScrollBehavior | 'horizontalOnly' or 'bothAxes' | | changeHighlightStyle | DiffChangeHighlightStyle | 'lineOnly', 'inlineOnly', or 'both' | | lineNumberStyle | DiffLineNumberStyle | 'dual' (separate old/new columns, default) or 'single' (unified column). Unified mode only | | showsChangeMarkers | boolean | Show the +/ gutter column (default true). Combine 'single' + false for a minimal gutter | | contextCollapseThreshold | number | Lines before context is collapsed (default 8) | | visibleContextLines | number | Visible context lines around changes (default 2) | | gutterBackground | string | Gutter background color | | gutterText | string | Gutter text color | | backgroundColor | string | Overall diff background | | addedLineBackground | string | Added line row color | | removedLineBackground | string | Removed line row color | | addedHighlightBackground | string | Word-level added highlight | | removedHighlightBackground | string | Word-level removed highlight | | hunkHeaderBackground | string | Hunk header background | | hunkHeaderText | string | Hunk header text color | | fileHeaderBackground | string | File header background | | fileHeaderText | string | File header text color | | fileMetadataText | string | File metadata text color | | separatorColor | string | Separator color | | borderWidth | number | Diff border width (set 0 to remove) | | borderColor | string | Diff border color |

Contributing

License

MIT