Skip to the content.

Ramus

Java-based IDEF0 & DFD modeller. Build business-process models in the IDEF0 and DFD notations, keep them in git, and edit them by hand.

The Ramus application window

Another view of the Ramus application window

By Vitaliy Yakovchuk. Free software under the GNU GPL, version 3 — see License.


Contents


Download

Packaged builds are on the Releases page: the macOS DMG and the Windows installer are built by CI and attached to the release of a v* tag. To build them yourself, see Building; to run the application from source, see Quick start.


Quick start

You need a JDK and a desktop session. Gradle itself is not required — the wrapper downloads it.

git clone https://github.com/Vitaliy-Yakovchuk/ramus.git
cd ramus
./gradlew runLocal

The first run fetches Gradle and roughly 180 MB of dependencies; later runs start in seconds.

Open a model straight away instead of going through the dialog:

./gradlew runLocal -Popen="dest/doc/en/Enterprise activity.rsf"

Sample models live in dest/doc/en/ and dest/doc/ru/.

JDK version. Tested on Temurin 21; JDK 17 or newer is expected. The build pins no toolchain, so sources compile against whatever JDK runs Gradle. Packaging a macOS DMG additionally needs a full JDK 21+ with jdeps, jlink and jpackage.

No JDK on the machine? See Docker below — it builds and runs without installing anything but Docker itself.


Project format

The application reads and writes .rsf — a ZIP of XML table dumps. It is the only format it opens and the only one it saves.

The YAML project tree

Beside it the tree carries a text format: a project as a directory of YAML files, made to be read, diffed and edited by hand.

Model.ramus/
├── project.ramus          entry point: schema version, plugins, counters
├── attributes.yaml        every attribute of the model
├── qualifiers/            one file per qualifier
├── properties/            model settings
├── attachments/           user attachments (reports, files)
├── .gitignore
└── .local/                UI state; excluded from version control

Consequences worth knowing:

It goes into git as it is. Writing it is deterministic, so converting an unchanged model rewrites no file and git status stays quiet until the model itself actually changes. There are no timestamps in the files, deliberately — they would make every write look like a change.

It is meant to be edited by hand. The YAML dialect is restricted on purpose: block style, sorted keys, quoted strings, no anchors or aliases, no line wrapping. One line in the file is one line of the value, so sed works and a diff points at the change rather than the paragraph around it. Editing values is safe; inventing identifiers is not — add new elements in the application, then edit them in the files.

project.ramus is the entry point. It carries the schema version, the application-version, minimum-version and the required plugins, and its presence is what makes a directory a project.

The application neither opens nor saves it. A project handed to it — the directory or that file — is refused with a message naming it. The tree is reached through the converters, which read and write it with the same code the application uses for the model itself:

./gradlew :ramus-core-demo:rsfToYaml -Prsf=<file.rsf> -Pout=<directory>
./gradlew :ramus-core-demo:yamlToRsf -Pin=<directory> -Prsf=<file.rsf>

So the way to edit a model as text is a round trip: convert it out, edit the files, convert it back, open the .rsf.

Full reference: docs/PROJECT_FORMAT.md.


Building

Runnable JAR

./gradlew :local-client:shadowJar
java -jar local-client/build/libs/ramus.jar

Docker

Builds in a container, so no JDK on the host:

docker build --target artifacts --output out .   # out/ramus.jar
docker build --target test .                     # run the test suite
docker build -t ramus .                          # image that runs the GUI

Running the GUI from the container needs an X11 socket and an auth cookie — the recipe, the CI notes and the reasoning behind the Dockerfile are in docs/DOCKER.md.

macOS application and DMG

./packaging/macos/build-dmg.sh          # one command: checks, builds, reports

The script picks a JDK (21 or newer, --jdk PATH overrides it), runs the Gradle pipeline, and prints where the image landed and how to install it. It refuses to run anywhere but macOS, because jpackage, iconutil and sips exist only there.

Under the hood it is still Gradle, and the tasks can be called directly:

./gradlew :local-client:createMacApp     # dev bundle, local-client/build/mac-app/Ramus.app
./gradlew :local-client:macDmg           # standalone DMG in dest/macos/

macDmg runs the full pipeline: .icns from packaging/macos/AppIcon.appiconsetjlink runtime → jpackage. The resulting DMG bundles a Java runtime, so its users need no Java. If jlink is unavailable the full JDK is bundled instead — larger, but it works.

The DMG is tied to one architecture, because the runtime inside it is: a build made on Apple silicon does not run on an Intel Mac. The architecture is part of the file name (Ramus-2.0.2-arm64.dmg), and .github/workflows/macos-dmg.yml builds both on GitHub’s runners — on a tag push it attaches them to the release. No Mac needed to publish a build.

Installing. Open the DMG, drag Ramus into Applications. Nothing else — the Java runtime is inside the bundle.

The application is not signed with an Apple Developer ID, so a Mac that downloaded it from the internet quarantines it and reports that “Ramus is damaged”. It is not; macOS says that about everything unsigned. Either open it once through the context menu (right-click → Open → Open), or clear the flag:

xattr -dr com.apple.quarantine /Applications/Ramus.app

Pointing packaging at a specific JDK, without touching your shell’s JAVA_HOME: create gradle-local.properties in the repository root (it is gitignored).

packagingJavaHome=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
# packagingUseJlink=false          # bundle the full JDK instead of a jlink image
# packagingJmodsPath=…/jmods       # explicit module path for jlink
# packagingLocales=en,uk,ru,pl     # locale data kept in the jlink runtime

The bundled runtime keeps locale data for English, Ukrainian and Russian only. Without it dates and Cyrillic sorting fall back to the root locale, and with all of it the image grows by about ten megabytes; packagingLocales is the dial between the two.

Windows installer

.\packaging\windows\build-installer.ps1     # one command: checks, builds, reports

The script checks the environment (Windows, a full JDK 21+, WiX Toolset 3) and runs the Gradle pipeline, which can also be called directly:

.\gradlew.bat :local-client:winInstaller                        # MSI in dest\windows\
.\gradlew.bat :local-client:winInstaller -PpackagingWinType=exe # EXE instead

Building needs WiX Toolset 3 (choco install wixtoolset): jpackage from JDK 21 drives WiX 3, support for WiX 4 and 5 arrived only in JDK 24. Like the DMG, the installer can only be built on the system it targets — .github/workflows/windows-installer.yml does it on GitHub’s runners, and on a tag push attaches the result to the release.

Installing. Double-click, and that is the whole procedure:

The package is not signed, so SmartScreen greets a freshly downloaded installer with “Windows protected your PC” → More infoRun anyway. Only a code signing certificate removes that.

The old NSIS and IzPack path (./gradlew windowsInstaller) is still in the tree but superseded: it hunts for a system JRE 1.6 and, failing to find one, downloads it from a Sun URL that has not existed for over a decade.


Documentation

The design documents under docs/ are written in Ukrainian.

Document What it covers
docs/PROJECT_FORMAT.md Complete project-format reference: syntax, identifiers, attribute types, how IDEF0 maps onto the files, safe-editing recipes
docs/AGENT_GUIDE.md The procedure an agent follows to edit a model in the files, and where it must stop
docs/FORMAT_MIGRATION_PLAN.md Why the format changed and how the migration was carried out, stage by stage
docs/START_REVIEW.md The storage subsystem as it stood before that work — the baseline for comparison
docs/DOCKER.md Containerised builds, running the GUI from a container, CI notes

Contributing

Bug reports, fixes, documentation and packaging improvements are all welcome — open an issue or a pull request.


License

GNU General Public License, version 3. The full text is in LICENSE.

Copyright © 2005–2026 Vitaliy Yakovchuk.

Ramus is free software: you may redistribute it and modify it under the terms of the GPL. It comes with no warranty — see sections 15 and 16 of the license.