# schemio: interactive diagrams that behave like the thing they document

> Schemio is a web based diagramming app where shapes can carry event handlers, animations and links to other diagrams, so a diagram can behave rather than merely illustrate. It runs as a hosted service, as a self hosted server configured through five environment variables, or as a static export hosted anywhere.

**ishubin/schemio** — Web based diagramming app that lets you build interactive diagrams and prototypes

- Repository: https://github.com/ishubin/schemio
- Website: https://schem.io
- Stars: 563 · Forks: 35
- Language: JavaScript
- License: MPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ishubin-schemio

## A diagram where the shapes do something

Schemio is a web based diagramming app that allows you to build interactive diagrams, and the framing in the README is careful about the priority. Although originally Schemio was not designed for this, it is also possible to use it as a prototyping app. So the interaction is the feature and the prototyping is the side effect, which is a different order from most tools in this space.

The feature list explains what the interaction actually is. The behavior editor lets you assign event handlers to any item, with events like init, click, mouse in and mouse out, so a shape is not a picture of a thing but an object that reacts. There are various animation functions, so you can have smooth transitions like fade in or fade out, move items and render particle effects, and the frame animation editor makes it possible to use frame based animations for any property, which is the mechanism behind those transitions.

The relative transformations feature is the one that makes the diagrams readable rather than merely animated. You can attach items to other items in your diagrams and tweak rotation, pivot point and scale, so a child follows its parent and the whole structure moves as one. Without that, a diagram with a hundred elements becomes a hundred things to drag individually.

Around that there is the ordinary diagramming surface. You can draw free-form shapes, document individual items in your diagrams, and link diagrams, either to other diagrams or to external documents.

The component based diagrams feature is what turns a set of pictures into a system. You can load diagrams dynamically inside of each other, which allows you to manage your diagrams better and lets the user discover more and more while staying in the original document.

## Export paths, and the static site that runs anywhere

There are two export routes, and the second one is unusual enough to be worth understanding.

The first is exporting an entire diagram or only selected objects as SVG, which is the obvious one and the one you want for a document or a slide deck. Because the output is SVG rather than a raster, a diagram exported this way stays sharp at any size and can be edited in a vector tool afterwards.

The second is generating a static version of all of your diagrams so that you can host it anywhere, even on GitHub pages. That is a different product from a hosted editor. Instead of a server that renders a diagram when someone requests it, you get files on disk that any static host will serve, which means the whole documentation set of interactive diagrams can live in the same repository as the code it documents, on a free host, with no server to keep running.

That pairing is what makes the tool interesting for engineering documentation. A diagram that links to other diagrams and responds to clicks can still be published as static files, so the interactive part survives the move to a static host. A conventional tool that stores diagrams in a database and renders them server side loses the whole point when you move to GitHub pages.

The project also ships a worked example of that idea. There is a demo built with Schemio containing interactive diagrams that answer a popular interview question, what happens when you open a website in your browser, and it is published as a static site, with the source in a separate sre-knowledge-base repository. The link into the diagram is a hash route, so the diagrams are deep-linkable, which means a reader can be pointed at one specific diagram rather than at an index.

There is also a video introducing interactive diagrams with Schemio, linked from the README.

## The five environment variables that configure a self hosted instance

The server-based version is configured entirely through five environment variables, and the table of defaults is short enough to read as a deployment checklist.

SERVER_PORT defaults to 4010 and is the server listening port. FS_ROOT_PATH defaults to /opt/schemio and is the path to Schemio storage on the file system, which is where it stores all your diagrams and uploaded files. FILE_UPLOAD_MAX_SIZE defaults to 10485760, which is the upload size limit for media files, and the default is ten megabytes. VIEW_ONLY_MODE defaults to false, and if set to true it does not allow editing, only viewing of folders and diagrams. ROUTE_PREFIX has no default and is a custom route prefix for all server endpoints, used in case you want to serve Schemio next to other web services on the same port, for example in a load balancer, so you can specify a custom route such as /schemio, and the description insists it must start with a slash.

Two of those deserve a comment. VIEW_ONLY_MODE is a one-way switch into a read-only instance, which is what you want for a documentation site where the diagrams are curated by a few people and consumed by everyone else. And ROUTE_PREFIX exists because the alternative is a reverse proxy configuration per deployment, which is exactly the sort of thing that gets forgotten until a deployment breaks.

The hosting story is straightforward. A Dockerized version is available on Docker Hub, and the run command in the documentation is:

```
docker pull binshu/schemio:latest

docker run -v "$(pwd):/opt/schemio" \
    -p 4010:4010 \
    -e FS_ROOT_PATH=/opt/schemio \
    -e SERVER_PORT=4010 \
    binshu/schemio:latest
```

The volume mount is what makes the instance persistent, and the two environment variables are passed explicitly even though the defaults would match, which is the right habit for a container that writes user data. The README also adds a warning that is easy to skip and expensive to ignore: don't forget to pull latest changes, as Schemio is frequently updated.

## The container image, and what the two stage build is doing

The Dockerfile is a two stage build and the second stage is the interesting part, because it shows what the server actually needs at runtime.

The build stage is node:17 as build. It copies the package files first and runs npm install, which is the standard layer caching so that dependency installation is only redone when the manifest changes. Then it copies src, assets, html, the webpack configuration files, all-tests.js, the test directory and the babel configuration, runs npm test, and finally runs the production app build and the static app build.

Running the tests inside the image build is worth noticing. It means a broken build fails at docker build time rather than at container start, which is a meaningful difference for anything running in a deployment pipeline.

The runtime stage is node:17-bullseye-slim with the working directory at /usr/bin/app. It copies the entry script in and makes it executable, then copies only what is needed: the assets directory and the html directory from the build stage, node_modules, the built assets JavaScript, and the server and common directories from src. The entrypoint is the entry script.

What that list tells you is that the runtime image does not include the source of the front end or the test directory. The server JavaScript, the common shared code and the compiled bundles are what the process actually needs.

The slim variant of the node image is also the right choice here, since the application is a server rendering diagrams and serving assets rather than something with a native toolchain at runtime. The heavier bullseye-slim base is what the node 17 slim tag provides.

The image is published under the name binshu/schemio on Docker Hub rather than under the project's own name, which is the one practical gotcha for anyone following the documentation: the project is schemio and the image is binshu/schemio, and the README's own run command uses the latter.

## A JavaScript project with five build targets and a desktop shell

The repository layout shows a project with several distribution shapes rather than one web app.

The package.json is named schemio at version 0.32.2, and the scripts are the clearest description of what it produces. There is a build-app-dev and a build-app-prod, a build-standalone, a build-playground, a build-ui-static-app-prod, and a set of start scripts that differ by which server they run: start for the main app, light-start, start-drive, start-static and start-electron. The webpack configuration files at the repository root match, with separate ones for the app, the standalone build, the drive build, the static build, the electron main and renderer processes, and a rules file and a standalone production file.

The standalone and static variants are the ones that produce the export paths described earlier, and the drive variant appears to be a separate deployment mode with its own server file.

The electron side is a full desktop application rather than a wrapper. There are forge.config.js for electron-forge, an entitlements.plist, a generate-electron-app-icons.sh script and a webpack.electron.main.config.js alongside the renderer one, and the package.json has package-electron and make-electron scripts. The make script is the distribution step that produces an installer, which is a meaningfully different deliverable from a hosted service.

There is also a set of build helper scripts at the root that give a sense of what is generated rather than hand written: build-fonts.py, build-global-art.py, build-template-index.py, build-drive-app.sh, an export-patcher-schema.js with its own webpack config, an analyze-webpack-bundle.sh, a release.sh and a release-notes-generator.sh, and a docker-entry.sh. The ai/ directory at the root is also a signal that the project has an AI-assisted component, and the addLicenseHeaders.sh script with the .license.header.js and .license.header.vue files, plus a .license-headers.yaml, shows that MPL-2.0 headers are enforced mechanically across the source.

The licence is the Mozilla Public License 2.0, and the notice in the README is the standard MPL text, which means changes to the covered files stay under the MPL while larger works can combine it with other licences.

## Conclusion

schemio suits someone documenting a system where a picture cannot convey the behaviour, since you can attach a click handler to a shape and link diagrams together, which turns a diagram into something a reader can explore. It does not suit you as a general whiteboard or a collaborative editor, and the readme frames it as a diagramming app that happens to work as a prototyping tool rather than the other way round. Before you self-host it, read the five environment variables, because VIEW_ONLY_MODE and ROUTE_PREFIX determine how the service is exposed, and note that the Docker image is on Docker Hub under a different name from the project.

## FAQ

### What makes schemio diagrams interactive?

The behavior editor lets you assign event handlers to any item, with events like init, click, mouse in and mouse out, and there are animation functions and a frame animation editor that supports frame based animations for any property. Items can also be attached to other items with relative transformations for rotation, pivot point and scale.

### How do I run a self hosted schemio server?

Use the Docker image with docker pull binshu/schemio:latest, then run it with a volume mount to /opt/schemio, the 4010 port published, and FS_ROOT_PATH and SERVER_PORT set as environment variables. The server is configured entirely through five environment variables: SERVER_PORT, FS_ROOT_PATH, FILE_UPLOAD_MAX_SIZE, VIEW_ONLY_MODE and ROUTE_PREFIX.

### Can schemio diagrams be hosted on a static site?

Yes. You can generate a static version of all of your diagrams so that you can host it anywhere, even on GitHub pages, and you can export an entire diagram or only selected objects as SVG.

### What licence is schemio under?

The Mozilla Public License 2.0. The repository enforces the licence headers mechanically, with a .license-headers.yaml configuration, a .license.header.js and .license.header.vue, and an addLicenseHeaders.sh script.

## Sources

- [ishubin/schemio on GitHub](https://github.com/ishubin/schemio)
- [License: MPL-2.0](https://github.com/ishubin/schemio/blob/master/LICENSE)
- [Project website](https://schem.io)
- [README](https://github.com/ishubin/schemio/blob/master/README.md)
- [Releases](https://github.com/ishubin/schemio/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ishubin-schemio
