Embed the engine in your application.
In about 30 minutes: a real host — an accounting system, an ERP, any line-of-business app on any stack — embeds a working DOCX editor with its own save pipeline. No Office installed, no external cloud, no installer: the engine is a single executable running next to your app.
How it works
Your application starts one process — the document processor. It owns the truth of the document: parsing, editing semantics, history, saving. Your app talks to it in two ways, and can use both at once:
- A visual editor in your window — the process serves an editing surface over localhost; you show it in the system WebView (WKWebView, WebView2, Android WebView).
- A headless command session — newline-delimited JSON over stdio, for automation with no UI at all.
Process lifecycle is your application's responsibility: start it when a document opens, stop it when you are done.
Path A — the visual editor in your window (~30 min)
1. Deploy the engine
Place the executable next to your application. One file, no dependencies, no installer.
2. Start the process
sumoffice-surface --port 0 --doc /absolute/path/contract.docx --save /absolute/path/contract-out.docx
--port 0 picks a free localhost port automatically. The first stdout line is the bootstrap message:
sumoffice.surface-host-bootstrap.v1
{ "url": "http://127.0.0.1:53817/?token=..." }
Read the url field. It carries a one-time 256-bit token — do not log it and do not persist it. The process binds to 127.0.0.1 only and serves both the editor assets and the document session on that single port.
3. Show the editor
- WKWebView (macOS/iOS): register a
WKScriptMessageHandlernamedsumofficeHost, create the web view, load the URL. - WebView2 (Windows): subscribe to
WebMessageReceived, navigate to the URL. - Android WebView / generic: listen for the
sumoffice-host-eventDOM event.
4. React to document events
| event | meaning |
|---|---|
ready | the document model is loaded; the editor is usable |
dirty | the user changed the document |
saved | the engine durably wrote the output file |
error | connection or save failure — show it, don't guess |
That's the whole integration. Success looks like: your window shows the document, a user edits a paragraph, dirty fires, save produces the output file, saved fires — and the saved file opens again in a fresh process with the edit intact. We don't count a save as done until the file has been reopened and verified.
Path B — headless automation (~10 min)
1. Start a session
sumoffice-cli serve
Readiness line on stdout:
{"ready": true, "schema": "sumoffice.session-serve.v1"}
2. Send commands — one JSON object per line on stdin
{"id":"1","cmd":"open","path":"/path/agreement.docx"}
{"id":"2","cmd":"mutate","operation_kind":"insert-text","paragraph_index":0,"offset":0,"text":"Hello. "}
{"id":"3","cmd":"save","path":"/path/agreement-out.docx"}
Responses echo your id so you can match them:
{"id":"1","ok":true}{"id":"2","ok":true}{"id":"3","ok":true}
Finish with {"id":"4","cmd":"shutdown"}.
The rules the engine keeps
- Commands run sequentially, in the order received.
- Every response carries your
id. - A refusal arrives before the change, not after. If an operation can't be applied safely, the document, its history and the file stay untouched.
- What the engine doesn't support, it preserves byte-for-byte on save — and tells you, instead of silently dropping it.
Spreadsheets
XLSX workbooks work identically: a separate processor binary, the same bootstrap, the same session protocol, the same refusal-before-change rule.
The reference integration — in your pocket
Our own mobile apps, SumDoc and SumSheet, are exactly this quickstart shipped to the app stores: a system WebView host around the same editing surface, the same bootstrap handshake, the same document events. No private APIs — the host apps use precisely what you just read. If you want to feel what your integration will behave like before writing a line of code, install them and open one of your own files.