Deploy Oberon to Europe — Niklaus Wirth's ETH Zürich Language in 2026
On January 1, 2024, Niklaus Wirth died at his home in Feldmeilen, near Zürich, Switzerland. He was 89 years old. The tributes that followed came from across the computing world — from former students who had passed through ETH Zürich's computer science department, from language designers who had built on his ideas, from engineers at Google who quietly acknowledged that Go's module system and type discipline owe more to Wirth's Modula-2 and Oberon than most people realize.
Wirth spent his entire career at ETH Zürich 🇨🇭, the Swiss Federal Institute of Technology, one of Europe's premier research universities. He could have left for Silicon Valley. He stayed in Switzerland. The languages he created — Pascal, Modula, Modula-2, Oberon, Oberon-2, Oberon-07 — were built in Zürich, for Zürich-manufactured hardware, taught in Zürich lecture halls, and influenced by the Swiss engineering tradition: do less, do it correctly, make it last.
The Wirth Language Family: A Swiss Engineering Legacy
Niklaus Wirth's programming languages span five decades and represent one of the most coherent and sustained efforts in language design in computing history.
Pascal (1970) was Wirth's first widely successful language, designed explicitly for teaching structured programming. Pascal became the dominant teaching language at European and American universities throughout the 1970s and 1980s. Apple used Pascal as the implementation language for the original Macintosh system software. Borland's Turbo Pascal became one of the most commercially successful programming tools of the 1980s. But Wirth was already thinking about what came next.
Modula (1975) and Modula-2 (1978) were Wirth's answer to the problems he saw with Pascal in large-scale systems: no module system, no separate compilation, no concurrency primitives. Modula-2 introduced modules as first-class language constructs — a revolutionary idea at the time. Code was organized into definition modules (the interface, what you can see) and implementation modules (the code, what you cannot see). This separation of interface from implementation is now the foundation of every modern module system, from Java packages to Go modules to TypeScript namespaces. Modula-2 was used to write operating system kernels, embedded systems, and compilers — serious systems programming where correctness mattered.
Oberon (1987) was Wirth's most radical simplification. Working with Jürg Gutknecht 🇨🇭 (also at ETH Zürich), Wirth designed Oberon as a language that could be learned in a weekend but was powerful enough to write an entire operating system. The Oberon System — a complete window-based OS written entirely in Oberon — was the proof. Project Oberon, published in book form with the full source code of the OS, remains one of the most impressive demonstrations in computing: a complete, working computer system that a single person can understand entirely.
Oberon's design philosophy was radical minimalism:
- Around 30 keywords (compare to C's 32 or Java's 50+)
- No header files, no preprocessor, no macros
- Garbage-collected memory
- Type-safe, with runtime bounds checking
- Module system from Modula-2, simplified
- Records with type extension (a clean approach to polymorphism without the complexity of full OOP)
The result was a language where you could read the entire language report in one sitting and understand every part of it. Wirth's famous aphorism, "A language that doesn't affect the way you think about programming is not worth knowing," was answered by Oberon itself.
GNU Modula-2 (gm2) — contributed by Gaius Mulley 🇬🇧 (UK) to the GCC project — brought production-quality Modula-2 compilation to Linux systems. gm2 is now part of the official GCC compiler collection and can compile Modula-2 code to native machine code with full optimization. The UK's contribution to the Wirth language ecosystem ensures that Modula-2 systems can be built and deployed on modern Linux infrastructure without relying on proprietary compilers.
Oberon+ (oberonc) — developed by Rochus Keller 🇨🇭 (Switzerland) — is a modern extension of the Oberon language with a JVM backend, bringing Oberon into the JVM ecosystem. Keller's work represents the continuing Swiss tradition of maintaining and extending Wirth's language family for contemporary use.
Rob Pike and Ken Thompson — while primarily associated with Bell Labs and Go's American origins — both interacted with Wirth's work extensively. Pike's Newsqueak and Limbo (predecessors to Go's concurrency model) drew on ideas from Oberon's lightweight module system. Go's package system, its emphasis on simplicity, its rejection of inheritance in favor of interfaces, and its design goal that "there should be only one obvious way to do something" are directly traceable to Wirth's influence. Europe invented the module system; the world adopted it.
Oberon's Technical Design: Why It Still Matters
Oberon's technical contributions were ahead of their time in 1987 and remain relevant in 2026.
Module System
Every Oberon program is composed of modules. Each module has a definition section (the public interface) and an implementation section (the private code). When you import a module, you can only use what is in its definition section:
DEFINITION WebServer;
TYPE
Context* = RECORD
path*: ARRAY 256 OF CHAR;
method*: ARRAY 16 OF CHAR;
END;
Handler* = PROCEDURE(ctx: Context; VAR response: ARRAY OF CHAR);
PROCEDURE Start*(port: INTEGER; handler: Handler);
PROCEDURE Stop*;
END WebServer.
The asterisk * marks exported identifiers — the public API. Everything without an asterisk is private to the implementation. This is clean, explicit, and prevents the accidental API surface explosion that plagues modern large codebases.
Type Extension (Records)
Oberon's approach to polymorphism avoids the full complexity of class hierarchies while still enabling extensible types:
MODULE APIHandler;
IMPORT WebServer, JSON, DB;
TYPE
Request* = RECORD
path*: ARRAY 256 OF CHAR;
body*: ARRAY 4096 OF CHAR;
END;
Response* = RECORD
status*: INTEGER;
body*: ARRAY 65536 OF CHAR;
END;
PROCEDURE HandleHealthCheck(ctx: WebServer.Context; VAR res: ARRAY OF CHAR);
BEGIN
COPY('{"status":"ok"}', res)
END HandleHealthCheck;
PROCEDURE HandleItems(ctx: WebServer.Context; VAR res: ARRAY OF CHAR);
VAR
rows: DB.ResultSet;
BEGIN
rows := DB.Query("SELECT id, name FROM items LIMIT 10");
JSON.SerializeRows(rows, res)
END HandleItems;
PROCEDURE Route(ctx: WebServer.Context; VAR res: ARRAY OF CHAR);
BEGIN
IF ctx.path = "/health" THEN
HandleHealthCheck(ctx, res)
ELSIF ctx.path = "/api/items" THEN
HandleItems(ctx, res)
ELSE
COPY('{"error":"not found"}', res)
END
END Route;
BEGIN
WebServer.Start(8080, Route)
END APIHandler.
No classes, no inheritance hierarchies, no virtual dispatch tables to manage. Modules compose cleanly. The entry point is just the BEGIN block at the bottom — executed when the module is loaded.
Deploying a Modula-2 Backend (GNU Modula-2 / gm2)
For systems that need maximum performance and minimal runtime overhead, GNU Modula-2 compiles to native machine code via GCC:
MODULE HttpServer;
FROM SysTypes IMPORT CARDINAL32;
FROM IOChan IMPORT ChanId;
FROM SockLib IMPORT Socket, Bind, Listen, Accept, Send, Recv;
FROM Strings IMPORT Append, Equal;
VAR
serverSocket, clientSocket : Socket;
buffer : ARRAY [0..4095] OF CHAR;
bytesRead : INTEGER;
PROCEDURE HandleRequest (client : Socket; request : ARRAY OF CHAR);
VAR
response : ARRAY [0..2047] OF CHAR;
BEGIN
IF Equal(request, "GET /health") THEN
response := "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\"status\":\"ok\"}"
ELSE
response := "HTTP/1.1 404 Not Found\r\n\r\n"
END;
Send(client, response, LENGTH(response), {})
END HandleRequest;
BEGIN
(* Server startup *)
serverSocket := Socket(AF_INET, SOCK_STREAM, 0);
Bind(serverSocket, 8080);
Listen(serverSocket, 128);
LOOP
clientSocket := Accept(serverSocket);
bytesRead := Recv(clientSocket, buffer, SIZE(buffer), {});
HandleRequest(clientSocket, buffer)
END
END HttpServer.
Dockerfile for gm2 (GNU Modula-2)
FROM debian:bookworm-slim AS builder
RUN apt-get update && apt-get install -y \
gm2 \
libgm2-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN gm2 -g -o http-server HttpServer.mod
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/http-server ./http-server
EXPOSE 8080
CMD ["./http-server"]
Dockerfile for Oberon+ (JVM backend)
FROM eclipse-temurin:21-jdk-jammy AS builder
# Install Oberon+ compiler
RUN apt-get update && apt-get install -y wget && \
wget -q https://github.com/rochus-keller/Oberon/releases/latest/download/oberonc-linux-x64.tar.gz && \
tar xzf oberonc-linux-x64.tar.gz -C /usr/local/bin && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN oberonc -src src -out build -main APIHandler
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY --from=builder /app/build ./build
EXPOSE 8080
CMD ["java", "-cp", "build", "APIHandler"]
sota.yaml
name: my-oberon-api
runtime: docker
port: 8080
region: eu-central-1
env:
- name: DATABASE_URL
secret: database-url
resources:
cpu: 0.25
memory: 128Mi
health:
path: /health
Performance Characteristics
Oberon and Modula-2 were designed for systems programming — direct memory access, minimal overhead, deterministic performance:
| Language | Binary Size | Cold Start | Throughput | Memory |
|---|---|---|---|---|
| gm2 (Modula-2) | ~200KB | <10ms | ~35,000 req/s | Minimal |
| Oberon+ (JVM) | ~5MB | ~200ms | ~18,000 req/s | Medium |
| Go | ~8MB | <10ms | ~45,000 req/s | Low |
| Rust | ~3MB | <10ms | ~50,000 req/s | Minimal |
| Node.js | ~40MB | ~400ms | ~12,000 req/s | High |
GNU Modula-2 produces native code comparable to C and Go in performance. The language's design — no garbage collector, deterministic memory management, simple module loading — means there are no GC pauses and no startup surprises. For embedded systems, IoT backends, and edge services where memory and startup time matter, a gm2-compiled Modula-2 binary is competitive with Rust or C.
Where Oberon and Modula-2 Are Used Today
Wirth's languages have a smaller community than Java or Python, but they have outlasted dozens of languages that had larger communities in the 1990s. The organizations that use them have typically made an active choice for long-term correctness.
Embedded Systems: Modula-2's combination of module safety and native compilation makes it suitable for embedded controllers in industrial equipment. Several European industrial automation companies maintain Modula-2 codebases that have been running correctly for decades.
Academic Computer Science: ETH Zürich still draws on Oberon for teaching in some courses, particularly those focused on systems programming and compiler construction. Wirth's books — Programming in Oberon, Compiler Construction, Project Oberon — remain standard references. The Oberon tradition of teaching systems programming by showing students a complete, understandable system has influenced how computer science is taught across Swiss, German, and Austrian universities.
Project Oberon 2013: In 2013, Wirth published a complete revision of Project Oberon — a full operating system, written in Oberon, for a simple RISC processor. The entire source code is approximately 4,000 lines of Oberon. One person can read and understand the entire system. This stands in deliberate contrast to Linux, which has millions of lines of code that no single person can comprehend. Wirth's point was that simplicity is a feature, not a compromise.
Language Research: The Oberon system has been used as a research substrate by groups at ETH Zürich, TU Vienna, and several Swiss universities because it is small enough to modify and study. Research on garbage collection algorithms, module loading, and type-safe systems programming has been conducted using Oberon variants as the implementation language.
Deploying to sota.io
# Install sota CLI
npm install -g sota-cli
# Login to sota.io
sota login
# Deploy from project root (Dockerfile required)
sota deploy
# View logs
sota logs --follow
# Check deployment status
sota status
sota.io provides EU data residency by default. Your Oberon or Modula-2 backend runs on servers in Germany and Switzerland — the same countries where these languages were created. No configuration required for GDPR compliance; it is built into the infrastructure.
Why European Infrastructure for Wirth's Languages
Niklaus Wirth designed languages in Switzerland for European computing infrastructure. He believed that software should be small, correct, and comprehensible — that a programmer should be able to understand everything their system does. This philosophy stands against the trend toward massive, opaque systems that rely on complexity to hide their defects.
Running Oberon or Modula-2 on European infrastructure is not nostalgia — it is a deliberate choice about the kind of software you want to write and where you want it to run. sota.io provides EU-native deployment with managed PostgreSQL and no operational overhead. Your binary, your data, your latency — all European.
| Feature | sota.io | AWS Frankfurt | Heroku |
|---|---|---|---|
| EU Data Residency | Native | Opt-in | Manual |
| GDPR by default | Yes | Configuration | Manual |
| gm2 / Oberon Docker | Yes | Yes | Limited |
| Managed PostgreSQL | Yes | RDS | Add-on |
| Binary deployment | Yes | ECR/ECS | No |
Getting Started
- Install GNU Modula-2:
apt install gm2on Debian/Ubuntu - Or install Oberon+: Download from the Oberon+ GitHub releases
- Write your module: Define your API with Modula-2 or Oberon module syntax
- Add a Dockerfile using the examples above
- Deploy:
sota deploy
sota.io detects your Dockerfile, builds the container, provisions a PostgreSQL database, and deploys to EU infrastructure.
Wirth language resources:
- GNU Modula-2 (gm2)
- Oberon+ compiler (oberonc)
- Project Oberon 2013 (Wirth & Gutknecht)
- Niklaus Wirth's papers and books
See Also
- Deploy Oberon-2 to Europe → — Niklaus Wirth 🇨🇭 + Hanspeter Mössenböck 🇦🇹 (ETH Zürich/JKU Linz 1991): the object-oriented extension of Oberon with type-bound procedures
- Deploy Modula-2 to Europe → — Niklaus Wirth 🇨🇭 (ETH Zürich 1978): Oberon's predecessor, the language that invented the module system
- Deploy ALGOL W to Europe → — Niklaus Wirth 🇨🇭 + Tony Hoare 🇬🇧 (Stanford 1966): the pre-Pascal language that introduced records and case statements
- Deploy Free Pascal to Europe → — Wirth 🇨🇭 Pascal + Hejlsberg 🇩🇰 Turbo Pascal: the actively maintained open-source Pascal compiler for EU infrastructure
- Deploy to Europe: All 104 Languages → — Complete guide to EU-native deployment for every language
Deploy Oberon or Modula-2 to Europe in minutes. Start for free on sota.io — EU-native PaaS, managed PostgreSQL, GDPR-compliant by default.