Well ungit is a web app (as opposed to a website) which simply means it got more logic on the front-end to make a better user experience in the end. All the animations and quick switching of state of specific parts of the ui can really only be done as a web app, whereas if you do a web site you switch out the whole page with something from the backend for each action. It's not really a node.js specific thing, it can be done with any kind of backend. Also ungit uses a REST-like (euhm, it could be more strictly REST) backend interface (the /api/ stuff) and normally you only serve data through a REST api rather than html.

Regarding the classes: Yup much better! In general composition is preferred over inheritance though. The way I'd do this is to have three classes: a FileViewModel, a LineByLineDiffViewModel and an ImageDiffViewModel; the FileViewModel either has a LineByLine or an Image; i.e. either file.diff = new LineByLine.. or file.diff = new ImageDiff, and where LineByLineDiffViewModel would have logic for doing /api/filediff calls and ImageDiffViewModel would have logic to do /api/imagediff stuff. This makes it clearer what is what (the you separate file handling and diff handling which are two different concepts) and also makes the diff view models more reusable and encapsulated (for instance we could have a in-client tutorial which used only the LineByLineDiffViewModel to show users how that works, without having to mix in the FileViewModel).

Separating them like that also free's you up to make the two backend calls more differentiated; right now /api/filediff and /api/imagediff gives almost the same result (for instance both containing lines) when they're actually quite different things (I'd guess we don't even need a /api/imagediff endpoint, only just something that gives an image at the current state and the state at HEAD)