The browser does the work.
The document stays here.
React and TypeScript for the editor. SQLite and WebAssembly to read the project. SVG to put the wireframe back in front of you.
From file to pages
Choose a .bmpr or drag it into the editor. sql.js reads the SQLite database in memory. The model preserves raw data and archive resources; pages become navigable. The opening limit is 100 MB.
From pages to canvas
The renderer interprets controls and draws them as SVG. rough.js adds an optional sketch style. Text, geometry, supported embedded images, and icons become visible elements; unresolved controls may display placeholders.
From canvas to corrections
Select one or more elements, move them, resize them, and edit text. Use the property inspector, duplicate, change stacking order, and undo or redo. Groups are edited as blocks; their individual children cannot be edited through the interface.
From project to handoff
Export the page as SVG or PNG. Extract text from all pages as Markdown, or data as JSON. Mermaid and draw.io infer approximate connections that need review. Downloading a .bmpr copy requires explicitly enabling experimental saving.
No document-processing backend
The app server, local or online, delivers HTML, JavaScript, CSS, and WebAssembly. The browser opens and processes the document: the editor does not upload it to a conversion server. Docker serves the app through Nginx; there is no need to mount a mockup directory inside the container.
A tab is not an archive
The open project and its history live in memory. There is no persistent autosave, online collaboration, or Dropbox synchronisation. Choosing a file from Dropbox simply means opening a file available on your computer.
Reloading the tab can lose changes that have not been downloaded. Keep the original document and use different names for copies.
The code has readable rooms
src/io handles reading and writing; src/model data and geometry; src/render drawing; src/editor history; src/export exports; and src/ui the interface. A practical division for checking the path from file to pixel.