2026-06-16·9 min read·sota.io team

Deploy Pharo Smalltalk to Europe — INRIA's Living Language in 2026

In 1972, Alan Kay wrote a memo at Xerox PARC. He called it "A Personal Computer for Children of All Ages." In it, he described a machine and a language designed around a single idea: that programming should feel like thinking. Objects sending messages to each other. No global state. No subroutines — just objects, responding to the world.

The language was Smalltalk. It introduced the world to object-oriented programming as a complete philosophy: everything is an object, every action is a message send, and the programming environment is itself a living system you modify while it runs. The Java-style OOP that dominates enterprise software is a pale echo of Smalltalk's original vision. Where Java has static classes and compilation steps, Smalltalk had a dynamic image you could reach into and reshape at runtime.

Smalltalk-80 became the reference implementation. It ran inside a system image — a snapshot of the entire runtime, including the IDE, the objects, the classes, and the running processes — that you could save, share, and resume. This was not a quirk. It was the design. Programming in Smalltalk means programming inside a living system.

Pharo is what happened when European researchers decided Smalltalk was too good to abandon. In 2008, at INRIA Lille — France's national research institute for computer science — a group of researchers led by Stéphane Ducasse forked Squeak (itself a Smalltalk-80 descendant from Apple) to create a clean, modern Smalltalk designed for research and production. Pharo is what Smalltalk-80 looks like when European precision meets forty years of accumulated lessons.

The European Roots of Pharo

Pharo is not a language with European connections. It is a language built by a European institution, for European research, funded by European public money.

Stéphane Ducasse 🇫🇷🇨🇭 (INRIA Lille-Nord Europe) is the research director who initiated and continues to lead Pharo. Swiss-educated and French-based, Ducasse runs the RMoD team (Rethinking Modeling with Objects and Dynamics) at INRIA Lille. RMoD is funded directly by the French government and the European Union through national research grants. Ducasse has published over 200 research papers on object-oriented design, software evolution, and dynamic languages — and Pharo is the research artifact that all of it runs on. He co-authored Pharo by Example, the canonical introduction to the language, which is available free online and has been downloaded over a million times.

Marcus Denker 🇩🇪 (INRIA Lille-Nord Europe) is a German software engineer and researcher at INRIA who works alongside Ducasse on the Pharo runtime. Denker's specialty is meta-programming — the ability for a running Pharo system to observe and modify itself. He built significant parts of Pharo's reflection infrastructure and the MethodProxy framework that makes Pharo's runtime introspection uniquely powerful. Denker holds a PhD from the University of Bern 🇨🇭.

Noury Bouraqadi 🇫🇷 and Luc Fabresse 🇫🇷 (IMT Lille Douai) — researchers at the Institut Mines-Télécom in Lille — contributed Pharo's robotics and IoT frameworks. Pharo runs on microcontrollers via PhaROS (Robot Operating System bindings) and Espruino boards. When French engineering schools teach embedded systems, a significant portion use Pharo. The Lille research cluster — INRIA + IMT + Université de Lille — is the world's primary Pharo research hub.

Lukas Renggli 🇨🇭 (University of Bern / ETH Zürich) led development of Seaside, Pharo's continuation-based web framework. Renggli was a PhD student at Bern when he became the primary maintainer of Seaside — a web framework unlike any other. Seaside stores the entire web session as a continuation: a snapshot of the computation at the point the user clicked "Submit." Server-side backtracking in a web application is not a hack in Seaside; it is the fundamental model. Renggli later moved to Google Zürich but Seaside remains one of the most architecturally sophisticated web frameworks ever built, and it runs on Pharo.

The Pharo Consortium — formed in 2013 — includes INRIA, Université de Lille, IMT Lille, Ecole des Mines de Douai, University of Bern, Barcelona Tech (UPC), and commercial members. European universities account for the majority of active Pharo contributors. This is not coincidental: Pharo was designed to be researchable, which means its internals are readable, its runtime is inspectable, and its community is academic.

What Pharo Brings to Modern Backends

Pharo is not a toy. INRIA uses it for production research tools. European banks have deployed Smalltalk-based systems — some running for over twenty years — because the live image model makes Pharo backends uniquely maintainable.

Live system modification without restart:

In Pharo, you can connect to a running production server and modify its behaviour without restarting it. Not by deploying a new container. Not by hot-reloading a module. You open a connection to the running image and change a method. The change takes effect immediately, for all future messages. This is not a debugging feature — it is the programming model.

"Modify a running service endpoint without restart"
OrderService >> processOrder: anOrder [
  | result |
  result := self validateOrder: anOrder.
  result isSuccess ifFalse: [
    self logRejection: anOrder reason: result message.
    ^ result
  ].
  ^ self fulfillOrder: anOrder
]
"Edit this method in a live Pharo image → change takes effect instantly"

Zinc HTTP Components — the standard Pharo HTTP layer:

"Zinc HTTP server — included in Pharo standard library"
| server |
server := ZnServer on: 8080.
server onRequestDo: [:request |
  | path |
  path := request uri path.
  path = '/health'
    ifTrue: [ZnResponse ok: (ZnEntity text: 'OK')]
    ifFalse: [
      path = '/api/orders'
        ifTrue: [self handleOrdersRequest: request]
        ifFalse: [ZnResponse notFound]
    ]
].
server start.
"Server is running. Edit handlers live while it serves traffic."

Teapot — Sinatra-inspired REST framework:

"Teapot: declarative routing for REST APIs"
Teapot on: 8080 start: [:teapot |
  teapot
    GET: '/api/users' -> [:req | UserRepository findAll asJson];
    GET: '/api/users/<id>' -> [:req |
      | user |
      user := UserRepository findById: (req at: #id) asInteger.
      user
        ifNil: [TeaResponse notFound]
        ifNotNil: [:u | u asJson]
    ];
    POST: '/api/users' -> [:req |
      | user |
      user := User fromJson: req body.
      UserRepository save: user.
      TeaResponse created: user asJson
    ];
    exception: Error -> [:ex :req |
      TeaResponse serverError: ex messageText
    ]
].

Magritte — meta-described objects:

"Magritte: describe your domain model once, get forms/validation/serialization free"
Object subclass: #Product
  instanceVariableNames: 'name price category stockCount'
  classVariableNames: '' poolDictionaries: '' category: ''.

Product class >> descriptionName [
  ^MAStringDescription new
    label: 'Product Name';
    accessor: #name;
    beRequired;
    maxSize: 100;
    yourself
]

Product class >> descriptionPrice [
  ^MANumberDescription new
    label: 'Price (EUR)';
    accessor: #price;
    min: 0;
    yourself
]

"From these descriptions, Magritte generates:
 - HTML forms (Seaside integration)
 - JSON serialization/deserialization
 - Input validation
 - REST API documentation
 — automatically, from one description"

PostgreSQL via GLORP or SqueakDBX:

"GLORP: the standard Pharo ORM, maps Pharo objects to PostgreSQL"
| descriptor |
descriptor := GlorpClassDescriptor for: Order in: GlorpSession.
descriptor
  table: 'orders';
  mapField: 'id' to: #id;
  mapField: 'customer_id' to: #customerId;
  mapField: 'total_eur' to: #totalEur;
  mapField: 'created_at' to: #createdAt.

"Query with Pharo blocks — type-safe at the Pharo level"
session read: Order where: [:each |
  each status = 'pending' and: [each createdAt > Date today - 7 days]
]

Deploying Pharo to European Infrastructure

Pharo applications are deployed as Docker containers running the Pharo VM with a headless image. The standard production setup uses Pharo 11 (or 12) with Zinc HTTP and a supervisor (Docker restart policy) for resilience.

Dockerfile for a Pharo web service:

FROM pharo/pharo:11.0

WORKDIR /app

# Copy your Pharo image and changes
COPY myapp.image myapp.changes ./

# Start Pharo headless with your image, running the HTTP server
CMD ["pharo", "--headless", "myapp.image", \
     "eval", \
     "MyApp startOn: 8080. Smalltalk at: #done put: (Semaphore new). (Smalltalk at: #done) wait"]

EXPOSE 8080

For sota.io deployment, the sota.yaml is simpler:

name: my-pharo-api
build:
  image: pharo/pharo:11.0
  command: |
    pharo --headless myapp.image eval \
      "MyApp startOn: 8080. (Semaphore new) wait"
port: 8080
database:
  type: postgresql
  version: 17

sota.io detects the PostgreSQL connection string automatically and injects it as DATABASE_URL. Your Pharo service is running in Frankfurt or Amsterdam within minutes, GDPR-compliant by default.

Why GDPR Compliance Matters for Pharo Teams

Pharo is particularly popular in European research institutions and enterprises where data locality requirements are strict. INRIA itself must comply with French and EU data protection requirements for any personal data processed in research. Several major European insurance companies and banks have run Smalltalk-based backend systems for decades — maintaining them through live image updates rather than redeployments.

When you host Pharo on US infrastructure — AWS, GCP, Google Cloud Run — your data is subject to the CLOUD Act, which gives US authorities extraterritorial access to data held by US cloud providers regardless of where the server is physically located. For INRIA research data, financial data, healthcare data, or any personal data of EU citizens, this creates compliance exposure that cannot be resolved by choosing an EU region on a US provider.

sota.io is incorporated and operated entirely within the EU. No CLOUD Act exposure. No data processed outside EU jurisdiction. For the Pharo community — which is predominantly European — this is the natural deployment target.

The Performance Envelope

Pharo is an interpreted language with a JIT compiler. Performance is not Pharo's primary value proposition — correctness, live modifiability, and developer productivity are. But Pharo is fast enough for most backend workloads:

WorkloadPharo 11 (Zinc HTTP)Node.js (Express)Go (net/http)
JSON REST API~8,000 req/s~12,000 req/s~45,000 req/s
DB-backed CRUD~2,500 req/s~3,500 req/s~12,000 req/s
Complex object graph~4,000 req/s~6,000 req/s~20,000 req/s

For APIs that receive tens of millions of requests per day, Pharo is not the choice. For research tools, internal APIs, financial backend services where correctness matters more than throughput, and systems where live modification is operationally valuable — Pharo is competitive with any dynamic language and dramatically ahead on developer productivity for complex domain models.

Getting Started

# Install Pharo
curl -L https://get.pharo.org | bash

# Start the Pharo IDE
./pharo-ui Pharo.image

# Or headless for CI
./pharo --headless Pharo.image eval "Smalltalk version"

For web development, the recommended stack in 2026 is Pharo 11 + Teapot + Zinc HTTP + GLORP (PostgreSQL). All components are available through the Pharo package manager (Iceberg, which uses Git under the hood):

"In a Playground in the Pharo IDE:"
Metacello new
  repository: 'github://zeroflag/teapot:master/source';
  baseline: 'Teapot';
  load.

Deploy to sota.io:

# Build a headless Pharo image for production
pharo --headless Pharo.image eval "
  Metacello new
    repository: 'github://myorg/myapp:main';
    baseline: 'MyApp';
    load.
  MyApp exportHeadlessImage: 'production.image'.
"

# Deploy
sota deploy

The Pharo Community in Europe

The European Smalltalk User Group (ESUG) has met annually since 1993. Its conferences rotate between European cities: Barcelona, Brussels, Prague, Edinburgh, Grenoble. The 2025 conference was in Lyon. ESUG is not a niche event — it draws practitioners and researchers from across the continent, with significant participation from INRIA, IMT, and European universities that use Pharo as their primary language for research programming.

Pharo's GitHub has over 3,500 stars and 500 contributors. The majority of significant commits come from the INRIA Lille cluster and associated European institutions. This is active, funded, professionally staffed development — not a weekend project. INRIA has been running Pharo development as a research platform since 2008, and it intends to continue.

For European engineering teams building complex domain software — insurance, banking, logistics, healthcare — Pharo offers something no other language does: a system that stays alive, that you can inspect and modify while it runs, backed by forty years of European computer science research and an active community that includes the people who built it.

sota.io puts that system on European infrastructure where it belongs.


Ready to deploy Pharo to Europe? Create a free account on sota.io — EU infrastructure, GDPR-compliant by default, managed PostgreSQL included. Your Pharo image is running in Frankfurt in under five minutes.