diffine 1.0.0
diffine: ^1.0.0 copied to clipboard
Compare two versions and show what changed — a diff engine and a side-by-side viewer in one package, for text and for pictures, to read or to type into.
Changelog #
This package's history. Each language Diffine ships for keeps its own changelog beside its own manifest, because they version independently.
vNext (2026--) #
1.0.0 - 2026-09-12 #
The first release. Diffine for Flutter is the React package's engine and view, written again in Dart — the same comparison, the same rows, the same palette down to the colour values, and the same answers for the same arguments.
Added #
-
TextDiffcompares two documents and draws what happened between them. Lines are matched first and then the words inside a pair that was edited, so a changed word is a changed word rather than a changed line. Every part of the view is an argument with a default —view,lineNumbers,markers,wrap,alignLines,collapse,context,connectors,syncScroll,header,navigation,search,summary,showInvisibles— so the same widget covers a full side-by-side with connectors and a bare column of lines in a panel too narrow for anything else.Only the lines a reader can see are built, whichever way those arguments are set: the panes are lists rather than columns, so a comparison of twenty thousand lines draws the forty on the screen and the scrollbar is still the length of the document. There is no
virtualizeto turn off, because there was nothing left to turn off. -
mode: DiffineMode.editoris the same view with the two panes made editable. The field's own text is see-through and its caret is not, and the lines behind it are painted — so a tinted row, a marked word and a highlighter's colours sit under text somebody is typing, while the field goes on being a field with the framework's own undo, input method, selection and accessibility.before/afterordefaultBefore/defaultAfterdecide whether the documents are the application's or the widget's,onBeforeChangedandonAfterChangedreport either way, andreadOnlytakes a side.applyChangesputs a pair of arrows on every change in the column between the panes, for the question a comparison of a saved version and a draft is usually read with: keep this, or put the other one back. -
ImageDiffcompares two pictures and draws what changed over both of them. Four views rather than one — side by side, faded over each other, wiped across, or the mask on its own — because no single one of them answers "did this move, or did it change colour".tolerancesets how much of a difference counts,ignoreAntialiasingdrops what a renderer's smoothing left behind, andalignfinds the offset between two shots that are not lined up.loupeshows the pixels under the pointer magnified, both sides at once, with the colour of the middle one written out and the point of the frame it sits at — because two panes at four hundred per cent say two pixels are different and stop there.The wheel zooms about the pointer, which
wheelturns back into moving the picture for a comparison sitting in the middle of a screen that scrolls.picturesis several rather than two, and passing it is what turns the list on: each gets a pane of its own with what that picture disagrees with the baseline about marked on it, and the pane holding the baseline is marked with everywhere anything disagrees.unchangeddecides what happens to the parts nothing happened to: drawn faint with the change at full strength, or not drawn at all so that the change is read as a picture on a plain ground rather than as a mark on one.A picture arrives as the bytes of a file, as a
ui.Image, or as a buffer of pixels. There is no URL among them: fetching one is the application's to do.onChooseis the same refusal for opening a file — the widget draws the button and the application answers it, because a picker is a plugin and which plugin is the application's choice. -
diffImagescompares several pictures at once, andimagesSimilaritysays how alike they are. Three renderings of one screen, four exports of one asset, a saved version against the last five runs. Each picture is compared with a baseline exactly asdiffImagewould compare it, and the mask is a bit a picture rather than a kind — somask[pixel] != 0is "does anything disagree here" andmask[pixel] & (1 << i)is "does this one". A byte holds eight, which iskMostPictures. -
imageSimilarityanswers how alike two pictures are, in one number.diffImagesays where two pictures differ, which is the question a reader looking at them has; a build with a threshold in it, a report ranking a hundred screenshots and a badge on a screen are all asking the shorter one. What comes back is a share from 0 to 1, the counts it came from, how large each picture was, and how far apart the pixels are on average — because a photograph saved again is unalike in most of its pixels and barely apart in any of them, and one number cannot say both. -
The engine is its own thing.
diffText,diffWords,diffCharacters,diffSequence,diffImage,imageSimilarity,paintDiffImage,parsePatchandformatPatchtouch no widget at all, so a build script, an isolate or a test can call them and hand the answer to the widget as a value.diffSequencetakes any two lists of tokens, for an application whose pieces are neither lines nor words. -
parsePatchreads a unified diff into exactly whatdiffTextreturns, down to the words marked inside a pair of changed lines, andformatPatchwrites one back out. A service that already holds the comparison can send a few kilobytes of patch instead of a few megabytes of documents. Where a patch is missing lines the numbers jump, and the viewer draws a band saying how many rather than pretending line 7 sits above line 40. -
A search of its own for each pane, with a button in the bar above it, a bar underneath it, and Ctrl+F for whichever pane the keyboard is in. Case, whole words and regular expressions are three switches inside the box; in the editor Ctrl+H opens the same bar with a row for replacing under it.
-
languagecolours the two documents, from grammars that ship with the package. The identifiers are highlight.js's, so alanguagethat works in a browser works here, andkDiffineLanguagesis the whole list. The grammars are approximate on purpose — an app bundle has no network to fetch a real parser from, and colour is not the kind of answer that has to be right — and they never change the document: every run is cut out of the text it was given and the lengths add back up to the line.highlightis the way in for an application that has a highlighter of its own. -
renderGutterandrenderWidgetare where the application draws its own: a review comment, a coverage bar, a lint warning, a button for adding one. A widget is as tall as it is, and the line opposite is given the same height so the two sides stay level. -
DiffineThemeis the palette as a value. The React package declares every colour as a custom property and an application overrides the property; there is no cascade here, so the same names arrive as an object instead andcopyWithreplaces what an application means to change. It travels with the widget rather than through a global, so one comparison can be dark inside a light screen. -
English and Korean, through
locale, withstringsfor an application whose words are its own or whose language is neither. Everything the colours say is said in words as well: which side a pane is, what happened to each line, how many changes there are, and what every control does. -
No Material and no Cupertino. Nothing in the package imports either, so a comparison sits inside a
MaterialApp, aCupertinoAppor a bareWidgetsAppwithout bringing a second design system with it. The only dependency ischaracters, which is what Flutter already ships.