Deploy Raku to Europe β Cro HTTP Backends on EU Infrastructure in 2026
Most programming languages separate their type system from their parser. Types describe the shape of data after parsing; the parser is a separate concern, written in a parser combinator library or a generated tool like ANTLR. You parse the input first, get a raw tree, then validate against types. The two phases are distinct.
Raku does not do this. In Raku, grammars are first-class language constructs β built into the type system, composable like roles, and as reusable as modules. You define a grammar the same way you define a class. Rules inside grammars behave like methods. You inherit grammars. You compose grammars using roles. And the result of parsing is not a raw tree but a typed data structure that you control with action classes.
Raku (formerly Perl 6) was designed by Larry Wall πΊπΈ over twenty years, but its implementation β the MoarVM runtime, the Cro HTTP framework, and the modern compiler toolchain β is predominantly European work. The engineers who made Raku deployable at production scale in the 2020s are based in Sweden, the UK, and Continental Europe.
Raku applications deploy to sota.io on EU infrastructure with full GDPR compliance. This guide shows how.
The European Raku Community
Raku's language design is American in origin, but its production-grade implementation is a European engineering achievement.
Jonathan Worthington π¬π§ β British software engineer, based in Sweden β is the principal architect of MoarVM (the primary Raku virtual machine) and the creator of the Cro HTTP framework. Worthington joined the Rakudo project in the mid-2000s and has contributed more to Raku's production readiness than any other single engineer. His work encompasses the Raku type system, the native call interface, the concurrent and parallel infrastructure (react, whenever, Supply), the async/await model, and MoarVM's JIT compiler. Worthington is a partner at edument, a Swedish software education and consulting company based in Gothenburg and Stockholm β he has spent over a decade working in Sweden's technology ecosystem, contributing to both the Raku language and the broader European software education community. He is also associated with the IT University of Copenhagen (ITU) and DIKU (the Department of Computer Science at the University of Copenhagen π©π°), where concurrency research has long intersected with programming language implementation. Cro β the HTTP framework he created for Raku β is not a port of an existing framework but a ground-up design using Raku's supply/react concurrency model: HTTP requests arrive as events in a Supply, and handlers are composed from functional transformations. The result is an async-native HTTP framework that handles HTTP/1.1, HTTP/2, WebSocket, and TLS from the same compositional model.
Carl MΓ€sak πΈπͺ β Swedish software developer β is one of the most prominent Raku community voices in Europe. MΓ€sak has contributed extensively to Raku's documentation, community infrastructure, and language design discussions. He is best known for his annual Raku Advent Calendar β a series of detailed technical blog posts published each December, covering language internals, design decisions, and practical patterns. The Advent Calendar has become the primary learning resource for intermediate Raku developers who want to understand the language's deeper mechanisms rather than just its syntax. MΓ€sak has contributed to Cro, to Raku's test suite, and to the language's ongoing design discussions. His work represents the Scandinavian open-source software tradition β technically rigorous, pedagogically clear, community-minded.
Naoum Hankache π±π§π«π· β based in France β authored "Perl 6 Introduction" (now "Raku Introduction"), which became the standard entry-point documentation for developers learning Raku. Written in multiple languages and available freely online, it introduced Raku's multiple dispatch, gradual typing, and grammar system to developers across Europe and the Arab world. Hankache's documentation work has been central to Raku's adoption in the European developer community.
The Raku Foundation and European FOSDEM presence. Raku has had a consistent presence at FOSDEM β the Free and Open Source Software Developers' European Meeting held annually in Brussels π§πͺ. European Raku developers have presented language internals, production use cases, and framework development at FOSDEM's language-focused dev rooms. FOSDEM is the largest free software conference in Europe, and Raku's participation has connected the language to the broader EU open-source ecosystem.
Why Raku for EU Backends
Built-in grammar system with PEG semantics. Raku is the only general-purpose programming language with a PEG (Parsing Expression Grammar) parser system built into the language itself. grammar, rule, token, and regex are keywords, not library calls. You define a grammar as a class, inherit it like a class, and compose partial grammars using roles. For EU backends that need to parse structured data β SWIFT payment messages, HL7 FHIR health records, EDI B2B documents, or domain-specific configuration languages β Raku's grammar system eliminates an entire category of external dependencies and provides typed, validated parsing without runtime reflection.
Gradual typing with type-checked contracts. Raku supports both typed and untyped variables in the same codebase. my $x = 5 is untyped; my Int $x = 5 is typed and enforced at runtime. Parameter types in subroutines are checked at call time: sub process(Str $name, Int $age) will throw a TypeError if called with wrong types. This makes Raku suitable for incremental migration β start with dynamic prototyping, add types as your service stabilizes. For GDPR-compliant data pipelines, typed parameters mean personal data fields are validated at API boundaries.
Multiple dispatch for domain modeling. Raku's multi subroutines allow multiple implementations of the same function name dispatched by parameter type: multi sub render(ImageData $d) {...} and multi sub render(TextData $d) {...} are separate functions selected automatically by the runtime. This is not method overloading β it works across modules, allows fallthrough, and supports guards (where constraints). For EU backends that handle heterogeneous regulatory document types (invoices, contracts, GDPR consent records), multiple dispatch produces cleaner domain models than if/elsif type checks or OOP inheritance hierarchies.
Cro: async HTTP/2 + WebSocket from a supply model. Cro represents HTTP as a pipeline of transformations on a Supply of requests. This is not metaphor β the actual implementation uses Raku's reactive programming primitives (Supply, react, whenever) to compose middleware. Adding authentication is composing a transformation; adding rate limiting is composing another. The same model handles HTTP/1.1, HTTP/2, and WebSocket without different code paths. Cro generates TLS automatically and integrates with Raku's async/await for non-blocking I/O.
Lazy sequences for streaming data. Raku's sequence objects are lazy by default. (1..Inf).grep(*.is-prime).head(100) generates the first 100 primes without computing an infinite list β the sequence evaluates on demand. For EU backends that process large datasets β Eurostat statistical files, ECB financial time series, or GDPR-required data export requests β lazy sequences allow streaming processing without loading entire datasets into memory.
Roles for composable behavior. Raku roles are composable units of behavior that can be applied to classes at definition time or at runtime. A Serializable role that adds JSON serialization, a Auditable role that logs mutations for GDPR Article 5(2) accountability, or a Cacheable role that adds Redis-backed memoization can all be defined independently and composed into domain objects. Unlike mixin inheritance, roles conflict-check at compile time β if two roles define the same method, the composer gets a compile error rather than silent method resolution order surprises.
Cro: HTTP Services in Raku
Cro is the production HTTP framework for Raku, written by Jonathan Worthington π¬π§. It handles HTTP/1.1, HTTP/2, and WebSocket from the same compositional model, using Raku's supply/react concurrency primitives.
use Cro::HTTP::Router;
use Cro::HTTP::Server;
my $app = route {
get -> 'health' {
content 'application/json', %( status => 'ok' );
}
get -> 'api', 'users', UInt $id {
my $user = await DB.get-user($id);
content 'application/json', $user.to-hash;
}
post -> 'api', 'users' {
request-body -> %data {
my $user = await DB.create-user(%data<name>, %data<email>);
created "/api/users/{$user.id}", 'application/json', $user.to-hash;
}
}
}
my Cro::Service $server = Cro::HTTP::Server.new(
:host<0.0.0.0>, :port(8080), application => $app
);
$server.start;
react { whenever signal(SIGTERM) { $server.stop; done } }
Cro's routing uses Raku's native multiple dispatch β route segments are typed (UInt $id will reject non-integer path parameters automatically). await integrates with Raku's Promise-based async infrastructure.
Grammar System: Typed Parsing for GDPR Data
Raku's grammar system is uniquely suited to EU compliance scenarios where you need to parse and validate structured personal data:
grammar PersonalDataRecord {
rule TOP { <name-field> <email-field> <birthdate-field>? }
token name-field { 'name:' \s* <name-value> }
token email-field { 'email:' \s* <email-value> }
token birthdate-field { 'dob:' \s* <iso-date> }
token name-value { <[A..Za..z \-\']>+ }
token email-value { <[\w\.\-\+]>+ '@' <[\w\.\-]>+ }
token iso-date { \d**4 '-' \d**2 '-' \d**2 }
}
class PersonalDataActions {
method TOP($/) { make %( |$<name-field>.ast, |$<email-field>.ast ) }
method name-field($/) { make %( name => ~$<name-value> ) }
method email-field($/) { make %( email => ~$<email-value> ) }
}
my $result = PersonalDataRecord.parse($input, actions => PersonalDataActions.new);
die "Invalid personal data record" without $result;
my %record = $result.ast;
The grammar fails immediately on malformed input β no partial parse, no coercion. For GDPR-compliant import endpoints, this means personal data is either fully valid (and safely stored) or rejected with a parse error (and never written to the database). No silent truncation, no type coercion producing incorrect records.
Multiple Dispatch for Regulatory Document Routing
class InvoiceDocument { has Str $.invoice-number; has Num $.amount; }
class ConsentRecord { has Str $.subject-id; has DateTime $.consent-date; }
class DataExportRequest { has Str $.subject-id; has Str $.requesting-party; }
multi sub process-document(InvoiceDocument $doc) {
say "Processing invoice {$doc.invoice-number} for β¬{$doc.amount}";
await Billing.record($doc);
}
multi sub process-document(ConsentRecord $doc) {
say "Recording GDPR consent for subject {$doc.subject-id}";
await ConsentStore.record($doc.subject-id, $doc.consent-date);
}
multi sub process-document(DataExportRequest $req) {
say "Handling GDPR Article 20 export for {$req.subject-id}";
await DataExport.generate($req.subject-id, $req.requesting-party);
}
The runtime dispatches to the correct implementation based on the actual type of $doc. New document types extend the system by adding new multi implementations β no modification of existing code, no switch statement, no registration system.
React/Whenever: Concurrent Request Processing
Raku's concurrency model uses reactive streams (Supply) and the react/whenever syntax for event-driven programming:
use Cro::HTTP::Router;
my $user-events = Supplier.new;
route {
get -> 'events' {
# SSE (Server-Sent Events) stream
response.headers<Content-Type> = 'text/event-stream';
response.headers<Cache-Control> = 'no-cache';
my $supply = $user-events.Supply;
response.body = $supply.map: -> $event {
"data: {$event.to-json}\n\n"
};
}
post -> 'api', 'actions' {
request-body -> %action {
$user-events.emit: %action;
content 'application/json', %( queued => True );
}
}
}
Supply objects are lazy, composable, and backpressure-aware. .map, .grep, .throttle, and .share transform supplies without blocking. For EU backends implementing real-time audit streams (GDPR Article 5(2) accountability requirement), this model provides exactly the right abstraction: a transformable, filterable, subscribable stream of audit events.
Gradual Types and GDPR Data Validation
# Strict typing for personal data fields
subset EmailStr of Str where /^ <[\w\.\-\+]>+ '@' <[\w\.\-]>+ $/;
subset EUPostalCode of Str where /^ \d**4..5 $/;
subset BirthYear of Int where 1900 <= * <= 2010;
class GDPRSubjectProfile {
has Str $.subject-id is required;
has EmailStr $.email is required;
has EUPostalCode $.postal-code;
has BirthYear $.birth-year;
has DateTime $.consent-date is required;
has Bool $.marketing-consent = False;
}
# Construction fails at runtime with TypeError if constraints violated
my $profile = GDPRSubjectProfile.new(
subject-id => "subj-{now.to-posix.Int}",
email => $validated-email,
postal-code => $validated-postal,
consent-date => DateTime.now,
);
Raku's subset types add where constraints to any type. EmailStr rejects non-email strings at assignment time. BirthYear rejects years outside the valid range. For GDPR-compliant data ingestion, this means validation is in the type system β it runs on every assignment, not just at the API boundary.
Deploying to sota.io
sota.io detects Dockerfiles automatically. Raku applications deploy as containers:
FROM rakudo-star:2024.09
WORKDIR /app
COPY . .
RUN zef install --deps-only .
EXPOSE 8080
CMD ["raku", "-Ilib", "bin/server.raku"]
With the sota.io CLI:
sota deploy
The build runs in Germany. Your Raku application runs in Germany. Personal data processed by your application never leaves EU jurisdiction.
Environment Variables and Database
Cro reads environment variables via %*ENV:
my $port = %*ENV<PORT> // 8080;
my $db-url = %*ENV<DATABASE_URL> or die "DATABASE_URL required";
sota.io injects DATABASE_URL automatically when you provision a managed PostgreSQL database. The PostgreSQL connection from Raku uses DB::Pg:
use DB::Pg;
my $db = DB::Pg.new(conninfo => %*ENV<DATABASE_URL>);
# Parameterised queries β no SQL injection
my @users = $db.query('SELECT id, email FROM users WHERE country = $1', 'DE').hashes;
# Async query via Promise
my $result = await start { $db.query('INSERT INTO audit_log ...', ...) };
DB::Pg uses PostgreSQL's libpq C library via Raku's native call interface (NativeCall). Parameterised queries are mandatory β string interpolation into SQL is not the library's API. For GDPR-compliant audit logging, this means every database write is a typed, parameterised call with no SQL injection surface.
EU Infrastructure and GDPR Compliance
Raku application (Cro HTTP)
β
sota.io platform
β
Hetzner Germany (Frankfurt)
β
EU jurisdiction β no Cloud Act exposure
Deploying on sota.io means:
- No US Cloud Act jurisdiction β sota.io is a German company. Hetzner is a German company. No US corporate parent can receive a CLOUD Act production order for your EU users' data.
- GDPR Article 28 DPA β Data Processing Agreement available on request.
- Data residency guarantee β your PostgreSQL database and application containers run in Germany.
- TLS by default β HTTPS certificate provisioned automatically. Raku/Cro communicates with the outside world over encrypted channels only.
For Raku applications processing EU personal data β consent records, health data, financial transactions β sota.io provides the compliance layer that US-jurisdiction PaaS providers cannot.
Getting Started
Install Rakudo Star (the Raku distribution including zef package manager):
# Docker (recommended for deployment)
docker pull rakudo-star:2024.09
# macOS
brew install rakudo-star
# Ubuntu
apt-get install rakudo
Create a new Cro application:
zef install cro
cro stub http my-service my-service
cd my-service
cro run
Deploy to sota.io:
# Install sota CLI
curl -fsSL https://sota.io/install.sh | sh
# Authenticate
sota auth set-key YOUR_API_KEY
# Deploy from your project directory
sota deploy
Your Raku backend is live at your-project.sota.io on German infrastructure within minutes.
sota.io is the EU-native PaaS for Raku and Cro applications β GDPR-compliant infrastructure, managed PostgreSQL, and zero-configuration TLS. Deploy your first Raku application β