# Egon: a browser modeler for Domain Storyboarding

> Egon is a TypeScript and Angular application for drawing Domain Stories, the workshop format used in Domain Storytelling to explore how a piece of software works from a user's point of view. It ships as a static bundle, a Docker image or an online service, and it is a GPLv3 licensed tool from WPS with no public source beyond this repository.

**WPS/egon.io** — A tool to visualize Domain Stories in your browser

- Repository: https://github.com/WPS/egon.io
- Website: http://domainstorytelling.org
- Stars: 840 · Forks: 128
- Language: TypeScript
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/wps-egon-io

## A storyboard for a workshop, not a design document

Egon is described simply as a tool to visualize Domain Stories in your browser, and the project title gives it away: Egon, the Domain Story Modeler.

The background is Domain Storytelling, and the README points to domainstorytelling.org for more on the method itself, plus the Egon.io website for a user manual. The topic tags make the lineage clear too, with domainstorytelling, domain-driven-design, business-process, collaborative-modeling and modeling-tool among them.

The distinction that matters is between this and the tools most people reach for when they hear domain modelling. A domain model in the UML sense is a class diagram of the concepts in a problem domain. A Domain Story is a picture of a slice of work, laid out as a series of comic-like panels, where each panel shows one actor doing one thing to one object, and the strip of panels tells you how a use case actually unfolds. It is a workshop artifact. The point of drawing one is that a team of developers, designers and domain experts discovers misunderstandings in the conversation, not that they produce a diagram they maintain for years.

So Egon is a facilitation tool. It is a canvas where the story is drawn while the conversation happens, and it is a place where the result can be kept and looked at again.

The audience is a team doing domain discovery work, and the fact that it runs in a browser with no installation is the point, since in a workshop you want everyone looking at the same thing on a projector rather than each person running something locally.

The project comes from WPS, and the copyright in the licence is held by WPS, Workplace Solutions GmbH.

## Angular 21 and diagram-js do the drawing

The dependency list tells you what kind of application this is.

The framework is Angular, with the core packages at version 21.2.13, plus the Angular component kit for the interface and the Angular CDK. The build tooling is the Angular CLI and the custom webpack builder, and the tests run under Karma with Jasmine, including ng-mocks for the mocking layer.

The interesting part is the diagram-js family. diagram-js itself is the BPMN modelling library from the bpmn-io project, and it is joined by diagram-js-direct-editing for inline label editing, diagram-js-minimap for the overview map, and align-to-origin and bpmn-font as supporting pieces. There is also an icon font package, a colour picker from ngx-color-picker, and the usual rxjs, zone.js and immer-free utility packages.

So the drawing surface is not Egon's own. Egon builds a domain story modeler on top of the same modelling engine that powers the BPMN editors, which means the pan, zoom, selection, keyboard and direct-editing behaviour comes from a library that has been exercised by a lot of people.

That is a sound engineering decision and it also bounds the scope. A canvas built on diagram-js has a diagram metaphor: elements, connections, rules about what may connect to what. A domain story panel is a rectangle with a picture, an actor and an object, so mapping it onto a diagram model is natural, and the constraints of that model are inherited too.

The repository layout follows the Angular convention with src/, spec/ and several tsconfig files, and the top level also carries a .archlint/ directory, which turns out to be a build-time constraint rather than a lint rule you run by hand.

## archlint is a build gate, not a style preference

Most projects have a linter. Egon has an architecture linter, and it is one of the three things you are asked to run before committing.

The README states that before committing any changes or creating pull requests you should run the tests, run the formatter, and check architecture rules. The third item is the interesting one.

The package manifest shows how it runs.

```json
    "archlint": "node ./node_modules/ts-archlint/dist/index.js ./src/app"
```

ts-archlint is a tool that checks architectural rules against the source tree, and here it is pointed at the src/app directory. The rules themselves live in the .archlint/ directory at the repository root, and the architecture documentation in architecture.md is the companion document.

What this buys you is enforcement rather than guidance. A rule that says a certain layer must not import from another layer is checked on every build, so a violation fails before review rather than being caught in a code review comment. For a long-lived application with a large team, that is the difference between an architecture that survives two years and one that decays into a dependency tangle.

The other two gates are more conventional. Tests run through ng test under Karma, and the formatter is prettier, which runs on the src directory with a separate check mode.

```json
    "format": "prettier --write ./src",
    "format:check": "prettier --check ./src",
    "test": "ng test",
```

The three together are a reasonable shape for an Angular codebase of this size, and the architecture check is the one that differentiates it from a default setup.

## Three ways to get it, and one of them needs no build at all

The deployment section lists three options, and the first is the one most organisations should look at first.

The standalone version is a zip file. If your organisation already runs a web server, you copy the zip to that server and extract it there to make Egon available to your organisation. No Node.js, no build, no container runtime, and the result is a static application served by whatever web server you already have.

The Docker container is the second option, for teams that prefer to serve websites as containers and want to build their own image. The repository ships a ready-made image as well, published under the ghcr.io/wps/egon.io path.

```bash
docker pull ghcr.io/wps/egon.io:latest
docker run -p 4040:80 ghcr.io/wps/egon.io:latest
```

The port on the left is the host port, and the documentation notes that you replace 4040 with whatever port you want to use. The right-hand port is fixed at 80 because that is what the container serves on.

The third option is the hosted service, and the documentation frames it as the choice when you do not want to build and deploy Egon yourself. You can run Egon online at egon.io.

That hosted option is the one to think about carefully, because it determines who holds the data. Domain stories are workshop artifacts that contain the inside of your product, the way your users describe their work, and the names of the things in your domain. Whether that can live on someone else's server is a question for your organisation, and it is the reason the self-hosted paths exist.

## The Dockerfile is a two-stage build ending in nginx

The Dockerfile in the repository is short and does exactly what you would expect.

```dockerfile
FROM node:24-alpine AS build-stage
WORKDIR /app

COPY . .
RUN npm ci

RUN npm run build-prod
```

The build stage uses node:24-alpine, copies the source in, installs dependencies with npm ci, and runs the production build script.

```dockerfile
FROM nginx:1.29-alpine
COPY --from=build-stage /app/dist_build/egon /usr/share/nginx/html

EXPOSE 80
```

The runtime stage is nginx:1.29-alpine with the built application copied into the document root, and port 80 exposed. No Node.js in the final image, no application server, nothing but static files and nginx. That is the same shape as the standalone zip option, which makes sense since both serve the same build output.

The path in the copy instruction, /app/dist_build/egon, is the output of the production build, and it connects to the manual standalone build instructions in the README. There, the process is to update the version tag in package.json and in environment.prod.ts, run the ng build with the production configuration, which creates or updates the dist_build folder, and then run the zip script.

```bash
npm run zip
```

That script in the manifest uses a template of '%NAME%-%VERSION%.%EXT%', so the archive is named egon-xxx where xxx comes from the version tag in package.json. The result lands in a dist folder, and that zip is the artefact you copy to an existing web server.

The Dockerfile and the zip are two routes to the same output, which is a good sign for the build configuration: the production build that the container uses is the one your own server will serve.

## Where Egon is the wrong tool

The first wrong-tool case is a team that wants a domain model as a maintained artefact. Egon produces a story model, which is a snapshot of a conversation at a point in time. If your goal is a class diagram that the code is checked against, this is the wrong tool, and the architecture linter that Egon enforces is about the Egon codebase, not about your domain model matching your implementation.

The second case is a team that needs the model to become code. There is no code generation path here, no export to a modelling format that a generator consumes, and no mention of one. A story drawn in Egon is something a team reads and discusses, and if your process depends on turning the model into an artifact, that step is manual and unconnected.

The third case is an organisation with a data residency constraint. The hosted service at egon.io is the path of least resistance, and if your workshops cover unreleased product plans, that is the wrong path. The self-hosted zip and the container exist for exactly this reason, and both are simple enough that there is no good reason to use the hosted version when the data is sensitive.

On licensing, this is GPLv3, and the README is clear about it. The Egon code is licensed GPLv3.0, copyright WPS Workplace Solutions GmbH, with the standard redistribution and warranty clauses. The project also credits two dependencies under the MIT licence, diagram-js from Camunda Services GmbH and ngx-color-picker from Zef Oy, and it reproduces the MIT text alongside the GPL text, which is the correct way to handle a GPL project that incorporates MIT licensed code.

The GPL is the one term to weigh before you adopt. Running the tool internally as a web app is one thing, and the copyleft obligation only bites when you distribute it or offer it as a service, but in a consultancy or an internal-tools team that sometimes hands software to clients, that question needs an answer before deployment rather than after. The repository's own licence field is not recorded, so the LICENSE file and the README text are the authority here.

The release picture is also slightly odd, and worth a look before you pin a version. The tags are v3.2.1 from 2026-06-19, v3.2.0 from 2026-06-01 and v3.1.0 from 2026-03-10, while the manifest version field reads 4.0.0-dev. The last push was on 2026-09-09, so the tree is ahead of the newest tag.

## Conclusion

Egon suits a team running Domain Storytelling workshops who want a shared, browser based place to draw the storyboard and keep the picture, since the static build and the container both deploy easily onto an existing web server. It does not suit a team that needs a model to become production code, because the output is a visual story model rather than a design artefact, and it does not suit an organisation that needs the tool inside its own product. Before adopting, read the architecture documentation at architecture.md, decide between the hosted service and a self-hosted copy on the licence terms, and note that the last push was on 2026-09-09 with release tags v3.2.1 from 2026-06-19 while the manifest version reads 4.0.0-dev.

## FAQ

### What is Egon used for?

Egon is a tool to visualize Domain Stories in your browser, supporting the Domain Storytelling workshop format. It is used to draw story models of a slice of work while a team explores it together, with the domainstorytelling.org site for the method and egon.io for the user manual.

### How do I run Egon locally for development?

Install the dependencies with npm ci, then build and run it on a local development server with npm run start, which is the ng serve command. Egon is then accessible at http://localhost:4200.

### What must I run before creating a pull request to Egon?

The README asks for three things: run the tests with npm run test, run the formatter with npm run format, and check the architecture rules with npm run archlint, which invokes ts-archlint against the src/app directory using the rules in the .archlint directory.

### How do I deploy Egon without building it?

You can pull the published image with docker pull ghcr.io/wps/egon.io:latest and run it with docker run -p 4040:80 ghcr.io/wps/egon.io:latest, replacing the host port as needed. Alternatively, the standalone zip build can be copied to an existing web server and extracted there.

### What license is Egon released under?

Egon is licensed under GPLv3.0, copyright WPS Workplace Solutions GmbH, and the repository does not record a licence field in its metadata, so the LICENSE file and the README text are the authority. The diagram-js and ngx-color-picker dependencies it uses are under the MIT licence.

## Sources

- [Issues](https://github.com/WPS/egon.io/issues)
- [Project website](http://domainstorytelling.org)
- [README](https://github.com/WPS/egon.io/blob/main/README.md)
- [Releases](https://github.com/WPS/egon.io/releases)
- [WPS/egon.io on GitHub](https://github.com/WPS/egon.io)

---

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