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

unitydiff

v0.1.0

Published

Human-readable diffs for Unity scene, prefab, and asset files

Readme

unitydiff

Human-readable diffs for Unity projects. Stop staring at incomprehensible YAML — see what actually changed.

Assets/Scenes/Level3.unity
  Canvas / TopPanel / ScoreText
    ~ PlayerUI
      ~ fontSize: 36 → 42
      ~ color: rgba(1, 1, 1, 1) → rgba(1, 0.9, 0, 1)
  Player
    + Added BoxCollider2D
    ~ Transform
      ~ localPosition: (0, 0, 0) → (2.5, 0, 0)
    ~ PlayerController
      ~ maxHealth: 100 → 150
      + dashCooldown: 0.5

The problem

Unity stores scenes, prefabs, and assets as multi-document YAML. When you git diff a scene file, you get hundreds of lines of noise like:

   m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalPosition: {x: 2.5, y: 0, z: 0}

Nobody on your team knows what that means without opening Unity. Designers, artists, and producers are locked out of understanding what changed.

unitydiff parses Unity's YAML format semantically, matches objects by their persistent fileID, and tells you in plain English: "Player's position changed from (0, 0, 0) to (2.5, 0, 0)".

Four ways to use it

1. GitHub Action (automatic PR comments)

Add unitydiff to any Unity project. Every PR that touches .unity, .prefab, or .asset files gets an automatic comment with the human-readable diff.

# .github/workflows/unitydiff.yml
name: Unity Diff

on:
  pull_request:
    paths: ['**/*.unity', '**/*.prefab', '**/*.asset']

permissions:
  contents: read
  pull-requests: write

jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: drLemis/unitydiff@main

The action posts a collapsible Markdown comment with hierarchy paths, human-readable names, and change summaries. If no Unity files changed, it stays silent.

2. Web UI (no install, no CLI)

Open the web UI → — works for designers, artists, and producers who don't use the command line.

Features:

  • Drag & drop two Unity files to compare them instantly
  • Git integration — connect to GitHub, GitLab, or Gitea/Forgejo repos, pick branches and commits, compare directly
  • Hierarchy paths — see "Canvas / TopPanel / ScoreText" instead of just "ScoreText"
  • Scene hierarchy tree — visual tree view showing the full object hierarchy with changed nodes highlighted
  • Collapsible sections with change count badges
  • Copy as Markdown — one click to copy the diff for pasting into issues/docs
  • Runs entirely in your browser — no files are uploaded anywhere
  • Works offline — save the HTML file and open it locally

3. Git diff driver (automatic git diff)

Make git diff use unitydiff automatically for Unity files:

npx unitydiff setup         # configures local repo
npx unitydiff setup --global # configures all repos

This sets diff.unitydiff.command in your git config and adds the right .gitattributes rules. After that, git diff produces human-readable output for .unity, .prefab, and .asset files instead of raw YAML noise.

4. CLI

npm install -g unitydiff

Or use without installing:

npx unitydiff HEAD~1 HEAD

CLI usage

Compare two git refs

unitydiff HEAD~1 HEAD                      # Last commit vs current
unitydiff main feature/new-enemies          # Compare branches
unitydiff HEAD~1 HEAD --scenes              # Only .unity files
unitydiff HEAD~1 HEAD --prefabs             # Only .prefab files
unitydiff HEAD~1 HEAD --assets              # Only .asset files

Compare two files directly

unitydiff old/MainScene.unity new/MainScene.unity

Output formats

unitydiff HEAD~1 HEAD                      # Colored terminal (default)
unitydiff HEAD~1 HEAD -f markdown          # GFM markdown
unitydiff HEAD~1 HEAD -f json              # Structured JSON
unitydiff HEAD~1 HEAD --summary            # Just counts

Filter out noisy properties

unitydiff HEAD~1 HEAD --ignore m_LocalRotation m_LocalScale

Teams that don't care about rotation/scale changes can silence them entirely.

Supported file types

| Extension | Type | Supported | |-----------|------|-----------| | .unity | Scene files | Yes | | .prefab | Prefab files | Yes | | .asset | ScriptableObject assets | Yes |

What it detects

  • Added/removed GameObjects — new objects in the scene
  • Added/removed components — BoxCollider2D added to Player, etc.
  • Property changes — position, rotation, scale, colors, numbers, strings
  • MonoBehaviour field changes — your custom script fields (maxHealth, moveSpeed, etc.)
  • ScriptableObject changes — game config files, data assets
  • Vectors and colors — displayed as (x, y, z) and rgba(r, g, b, a) instead of raw YAML
  • Hierarchy paths — full object path like "Canvas / TopPanel / ScoreText"
  • Reference resolution{fileID: 12345} becomes "Player (Transform)" instead of an opaque number
  • Script name resolution — MonoBehaviour components show actual script names (e.g. "PlayerController") via .meta file GUID lookup
  • Prefab variant overridesPrefabInstance m_Modification blocks are flattened into individual property changes
  • Nested prefab instances — overrides grouped by target for multi-level prefab nesting, with added/removed component tracking
  • Animation curve summaries — keyframe arrays show count + duration instead of raw data (e.g. "[200 keyframes, 2.50s]")

Resilience

unitydiff is designed to handle real-world Unity files gracefully:

  • Large fileIDs — 64-bit fileIDs are stored as strings to avoid JavaScript precision loss
  • Binary blobs — detected and wrapped instead of crashing the parser
  • Huge arrays — AnimationClip keyframe data and similar large arrays are collapsed into summaries
  • Unparseable documents — skipped instead of failing the whole file
  • PrefabInstance overridesm_Modification entries are flattened into diffable properties
  • Script name resolution.meta file GUIDs are resolved to actual script/asset names automatically

How it works

Unity YAML files use a tagged multi-document format. Each object starts with:

--- !u!<classID> &<fileID>
  • classID identifies the type (1 = GameObject, 4 = Transform, 114 = MonoBehaviour, etc.)
  • fileID is a persistent unique identifier that survives edits

unitydiff:

  1. Splits the file into individual documents
  2. Parses each document's class ID and file ID (preserving large IDs as strings)
  3. Builds an object graph (GameObjects → Components → Properties)
  4. Walks the Transform hierarchy to construct full paths
  5. Matches objects between old/new versions by fileID
  6. Deep-compares properties and classifies changes
  7. Resolves fileID references to human-readable names
  8. Outputs the result in the requested format

Programmatic API

import {
  parseUnityFile,
  diffParsedFiles,
  formatMarkdown,
  createRefResolver,
  buildGuidMapFromGit,
  resolveMonoBehaviourNames,
} from 'unitydiff';

const oldFile = parseUnityFile(oldContent, 'Scene.unity');
const newFile = parseUnityFile(newContent, 'Scene.unity');

// Resolve MonoBehaviour script names from .meta files
const guids = buildGuidMapFromGit();
resolveMonoBehaviourNames(oldFile.objects, guids);
resolveMonoBehaviourNames(newFile.objects, guids);

const changes = diffParsedFiles(oldFile, newFile);
const resolver = createRefResolver(oldFile.objects, newFile.objects);
console.log(formatMarkdown([changes], resolver));

Roadmap

  • [x] CLI with terminal, markdown, and JSON output
  • [x] Web viewer with drag-and-drop comparison
  • [x] GitHub/GitLab/Gitea integration in the web UI
  • [x] Hierarchy paths for full object context
  • [x] Human-readable reference resolution
  • [x] Collapsible sections in web UI and markdown
  • [x] GitHub Action for automatic PR comments
  • [x] --ignore flag for filtering noisy properties
  • [x] Large fileID precision (string-based storage)
  • [x] Parser resilience (binary blobs, huge arrays, corrupt documents)
  • [x] Git diff driver (unitydiff setup for .gitattributes integration)
  • [x] .meta file GUID → script name resolution
  • [x] Prefab variant/override detection
  • [x] Nested prefab instance diffing
  • [x] Animation curve summaries (keyframe count + duration)
  • [x] Scene hierarchy tree view in web UI
  • [x] CI pipeline (test on Node 18/20/22, auto-publish on tags)
  • [x] Integration test suite (85 tests, performance benchmarks)

License

MIT