npm install @rasterex/viewer- 01
Load two revisions. PDF, DWG, DXF, DGN, IFC or TIFF, straight from disk.
- 02
Press Compare. One overlay comes back, colour coded by what changed.
- 03
Mark a change. It becomes an issue with a severity, and Show jumps the drawing back to it.
Load two revisions of the same sheet and press Compare. The engine returns a single overlay: black for what is only in the original, red for what is only in the revision, grey for what both share.
- Only in the original
- Only in the revision
- In both
Then the part that matters more than the overlay. Draw a cloud around a change and an issue opens on the right, with a title, a description, a severity and a status. Press Show on any issue and the drawing jumps back to the mark it came from.
That is the difference between a picture and a review.
The grey chrome is not ours
The demo has a dark header reading Document Control, a record bar with a project, a sheet number and a revision, and an issues panel down the right side. None of that is the engine. It is marked HOST, and a button in the corner puts your product name and your accent colour on it in ten seconds.
The drawing area between them is marked ENGINE.
That split is the proposition. You keep your product, your data model, your terminology and your users. We supply the middle.
Two things that decide whether it survives real files
Alignment. Demos use pre-aligned files. Real revisions do not share an origin, because someone moved the sheet or exported from a different template, and the overlay comes out as red mush. Interactive alignment is built in. Pick the same two points on each drawing and the comparison runs again on that alignment. One control in the interface, about twenty lines of integration.
Formats. PDF, DWG, DXF, DGN, IFC and TIFF, and over 250 in total. The demo compares two AutoCAD drawings straight from disk with no conversion step in front of them.
What it took to build
File handling, the comparison flow, alignment, mark-up, the issue panel and the host shell are a few hundred lines of TypeScript around one npm package.
$ npm install @rasterex/viewerconst viewer = new RasterexViewer({ container, viewerUrl });await viewer.mount();await viewer.ready(); await viewer.documents.openFile(fileA);await viewer.documents.openFile(fileB); viewer.compare.on("comparisonComplete", r => r.outputFileUrl);viewer.compare.compare({ backgroundFileName, overlayFileName });The full call sequence, the alignment path and the error states are in the guide How to compare drawing revisions in a web app. The issue panel is covered in How to add drawing issue management to a web app.
Every engine call the demo makes is listed in a Calls panel inside the demo itself. Open it and watch it fill as you work. Nothing on that page is pre-rendered.
What this demo does not do
Side-by-side panes are not locked to each other. Two viewer instances cannot be held in register without a viewport API, so the demo says so under the panes rather than pretending.
The review is not persisted. Close the tab and the issues are gone. In your product they would go into your database, against your work orders. That is the integration, and it is yours to write.
Comparison runs server-side, so the drawings are uploaded to the engine host. On a self-hosted deployment that host is yours.
Build your own
Paste this into Claude, ChatGPT, Gemini or any coding agent. It names the package, pins the calls that exist, and tells the model not to invent the rest.
Build a web app that opens and compares two engineering drawings.
Use the Rasterex drawing SDK. The package is @rasterex/viewer on npm.
This is the only drawing library you may use. Do not substitute pdf.js,
three.js, dxf-parser, canvas rendering or any other viewer. Do not invent
API methods. If you are unsure of a call, read the quick start at
https://docs.rasterex.com/docs/getting-started/quick-start instead of guessing.
Stack: Vite, TypeScript, one page, no backend, no auth.
npm install @rasterex/viewer
The SDK points at a hosted sandbox engine by default, so this runs with no
server of your own and no API key.
These calls exist. Use them and nothing else:
const viewer = new RasterexViewer({ container, viewerUrl });
await viewer.mount();
await viewer.ready();
await viewer.documents.openFile(file); // resolves with fileName
viewer.compare.on("comparisonComplete", r => r.outputFileUrl);
viewer.compare.compare({ backgroundFileName, overlayFileName });
viewer.compare.align(); // interactive, two points
viewer.tools.set({ action, group, enabled, style });
viewer.annotations.on("createdWithDetail", e => e.guid);
viewer.annotations.select({ guid });
viewer.navigate("FIT_TO_WINDOW" | "ZOOM_IN" | "ZOOM_OUT" | "ROTATE");
Build this:
1. Two file slots. Each one calls documents.openFile and shows the real file
name the engine returned, not the name from the input element.
2. A Compare button, enabled once both files are open. It calls compare.compare
and waits. The comparison runs server-side and takes a few seconds, so show
a spinner with an elapsed counter, not a frozen button.
3. The result is a new document at outputFileUrl. Open it. Black is what is
only in the first drawing, red is what is only in the second, grey is what
both share.
4. An Align button that calls compare.align, lets the user pick two matching
points, then runs the comparison again on that alignment.
5. A markup tool, and a panel listing every mark as a row.
Two rules, and they matter more than the features:
Nothing reaches the screen unless the engine produced it. No placeholder data,
no mock file names, no button that does not call something. If a capability
cannot be demonstrated, say so on the page.
Every label must be read back from what the engine confirmed, never from what
you asked it to do. A pane that says "Overlay" must say it because the engine
reported the overlay is open, not because a click intended it.
Keep all SDK usage in a single engine.ts. Nothing else imports the package.
Show every call in a visible log panel so the user can check your work.If drawings sit inside your product
Tell us what your customers keep asking for. If it fits we will say how, and if it does not we will say that too.
