Two minutes
With Rust (the version in rust-toolchain.toml) and wasm-pack installed:
# 1. build the engine into the editor's folder git clone https://github.com/CasualOffice/openpresent cd openpresent wasm-pack build crates/casual-slide-wasm --release --target web --out-dir ../../webapp/pkg # 2. serve the folder, over HTTP, from anything python3 -m http.server -d webapp 8080 # 3. open http://localhost:8080/editor.html and drop a .pptx on it
The out-dir is relative to the crate, so ../../webapp/pkg lands in the repository's webapp/pkg.
What the files are
| File | What it is |
|---|---|
editor.html | The editor. This is the only page a self-hosted install needs |
editor*.js, commands.js, ribbon*.js | The editor's modules: the command registry, the ribbon, the slides and the dialogs |
render.worker.js | A module worker that runs the engine off the page's main thread |
editor.css, ribbon.css, ribbon.tokens.css, icons.fluent.svg | The editor's look and icons. The sprite is fetched at run time, so it must be served too |
pkg/casual_slide_wasm.js, pkg/casual_slide_wasm_bg.wasm | The engine, built by wasm-pack |
index.html, docs.html, deploy.html, download.html, style.css, site.js | This website. Leave them out if you only want the editor |
Build the engine
The engine is the crate casual-slide-wasm, compiled to wasm32-unknown-unknown. Build it in release mode, with --target web so it loads as an ES module with no bundler. CI builds it the same way, with wasm-pack 0.14.0.
Headers and CSP
- Serve over HTTP or HTTPS, not
file://: the editor is ES modules and a module worker, which browsers do not load from disk. - Serve
.wasmasapplication/wasm. Most servers do; an old one may need the type added. - Every page carries its own Content Security Policy in a
<meta>tag. If you send one as a header too, the browser applies both, so the header must allow at leastscript-src 'self' 'wasm-unsafe-eval',worker-src 'self',connect-src 'self',style-src 'self',font-src 'self'andimg-src 'self' blob: data:. - No cookies, no storage of documents and no requests to any other origin: the editor needs nothing else.
Any path, any host
Every link and import is relative, so the folder works at the root of a domain or under any path, such as https://example.com/tools/present/editor.html. Nothing needs configuring.
Size and compression
The engine is the large file, most of it the fonts it lays text out with, so every visitor sees the same line breaks. Serve it compressed, with gzip or Brotli. Splitting the fonts out of the engine is tracked work.
The collaboration server
Co-editing (Share in the editor) needs casual-slide-collab-server, in server/casual-slide-collab-server. It serves the editor's folder and relays edits between the people in a room, in order. It never opens or stores a deck: each browser holds its own copy and applies the same edits. Without it, everything else on this page works as before; only Share does not.
# after building the engine as above cd server/casual-slide-collab-server OPENPRESENT_COLLAB_FILES=../../webapp cargo run --release # open http://127.0.0.1:8787/editor.html, choose Share, open the link in a second window
| Setting | What it does |
|---|---|
OPENPRESENT_COLLAB_BIND | The address to listen on. 127.0.0.1:8787 by default, so only this machine can reach it until you say otherwise |
OPENPRESENT_COLLAB_FILES | The editor's folder (webapp/ with its pkg/) to serve beside the session. The editor opens its connection to /collab on the origin it was loaded from, so serve both from one origin: this server, or a proxy in front of it |
- No TLS. Put it behind a proxy that terminates HTTPS and passes WebSocket upgrades on
/collab; the editor then connects withwss:. - No sign-in yet. The room key in the share link is the only capability: anyone with the link can join and edit. Keep the server on a trusted network until tokens land.
GET /healthzanswersok, for a load balancer or a container check.
How this site is deployed
This site is GitHub Pages, published by the workflow pages.yml on every push to main, the way OpenCalc publishes its own. It builds the engine with wasm-pack, copies webapp/ to the root of the site with the engine in pkg/, draws the slide pictures on the front page with our renderer, adds the slide gallery under gallery/, and deploys the lot. Copying the same steps into your own CI is a good way to self-host.
What is not here yet
- No sign-in for co-editing. The room link is the only capability; tokens, and resuming a dropped connection, are tracked work.
- No container image or package. Build from source as above.
- No SDK for embedding the editor in your own page. Serve
editor.htmlas it is, or link to it.