2026-04-09ยท8 min readยทsota.io team

Deploy Links to Europe โ€” Philip Wadler ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ (Edinburgh University 2006), the Language That Eliminated Web Tiers, on EU Infrastructure in 2026

In 2006, Philip Wadler ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ and colleagues at The University of Edinburgh published a paper titled "Links: Web Programming Without Tiers." It described a language that solved one of the most persistent problems in web development: the fact that a typical web application is written in three entirely different languages โ€” JavaScript on the client, Python or Java on the server, SQL in the database โ€” and that translating data between them is the source of most security vulnerabilities and most accidental complexity.

Links was a language in which a single program could express all three tiers. The Links compiler would emit JavaScript for client-side code, SQL queries for database access, and server-side handlers โ€” all from the same source. Type safety was preserved across the tiers. SQL injection was impossible. XSS was impossible. The database schema and the application types were the same thing.

The language arrived at a moment when the web was becoming the dominant computing platform, and when the security failures of the tier-mismatch model were becoming catastrophic. Links offered a different architecture: one language, one type system, one place to reason about your application.

Philip Wadler and Edinburgh University

Philip Wadler ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ is one of the most influential figures in the history of programming languages. He has spent most of his academic career at The University of Edinburgh โ€” one of Europe's oldest universities, founded in 1583, consistently ranked among the world's top ten computer science departments.

Wadler's contributions are extraordinary in their range:

His collaborators on Links included Sam Lindley (later Edinburgh and Heriot-Watt), Ezra Cooper, Jeremy Yallop, and James Cheney โ€” all at Edinburgh or nearby Scottish universities. The project was part of a broader European research programme in type-safe programming.

Links: Web Programming Without Tiers
Philip Wadler et al. ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ Edinburgh University, 2006

Problem: Web applications require 3 languages
  Client:   JavaScript  (DOM manipulation, UI events)
  Server:   Python/Java (business logic, session state)
  Database: SQL         (relational queries, persistence)

Translation overhead:
  JavaScript โ†” Python: JSON marshaling, type coercion
  Python โ†” SQL: ORM mapping, N+1 queries, injection risk
  JavaScript โ†” SQL: indirect, error-prone via server

Security failures:
  SQL injection:  unescaped string interpolation into SQL
  XSS:            unescaped string interpolation into HTML
  Both caused by: same language (strings) for code + data

Links solution: ONE language, three compilation targets
  links_program.links
    โ†“ compile to JavaScript  โ†’ client bundle
    โ†“ compile to SQL         โ†’ database queries (type-safe)
    โ†“ compile to server code โ†’ HTTP handlers
  Type checker spans all three: no untrusted strings reach DB/DOM

Links is a functional language in the ML tradition, with record types, variant types, and a rich type system. Its key innovation is tier annotations โ€” the type system tracks whether code is intended to run on the client, the server, or the database, and enforces that data crossing tier boundaries is properly serialised.

# Links syntax: functional, ML-inspired
# Single program targeting server + client + database

# Database table definition (Links syntax)
var contacts = table "contacts" with
  (name: String, email: String, city: String)
  tablekeys [["email"]]
  from database;

# Server-side query: compiles to SQL
fun getContactsByCity(city) server {
  query {
    for (c <-- contacts)
    where (c.city == city)
    [c]
  }
}

# Client-side handler: compiles to JavaScript
fun handleClick(e) client {
  var city = domValue("city-input");
  var results = getContactsByCity(city);  # RPC call, type-safe
  replaceNode(renderResults(results), "results-div")
}

# Type-safe XML construction: XSS impossible
fun renderResults(contacts) {
  <ul>
    {for (c <- contacts)
      <li>{stringToXml(c.name)} โ€” {stringToXml(c.email)}</li>}
  </ul>
}

The critical security properties:

# Continuation-based web programming
# Links handles session state without cookies/tokens

fun loginPage() {
  <form l:onsubmit="{handleLogin(name, password)}">
    <input l:name="name" type="text" />
    <input l:name="password" type="password" />
    <button type="submit">Login</button>
  </form>
}

fun handleLogin(name, password) {
  # Links continuation: server maintains session implicitly
  if (authenticate(name, password)) {
    mainApp(name)  # continuation: next page
  } else {
    <p>Login failed.</p>
  }
}

The l:onsubmit and l:name attributes are Links extensions to HTML. They create typed bindings between form inputs and server-side continuations. Session state is maintained on the server โ€” no JWT tokens, no cookie management, no client-side state.

Continuations and the Web

One of Links' most distinctive features is its use of continuations for web programming. A typical web application is a state machine: the user fills in a form, submits it, receives a response, fills in another form. Maintaining state across these HTTP requests is the job of sessions, cookies, and URL parameters.

Links handles this differently. A Links web application is written as a single sequential program with blocking I/O at page boundaries. The Links runtime captures the continuation of the program when a page is served, stores it on the server, and resumes it when the form is submitted.

Traditional web session management:
  Request 1 โ†’ server computes response โ†’ stores state in cookie/DB
  Request 2 โ†’ server loads state from cookie/DB โ†’ computes response
  Developer manages: serialisation, deserialisation, expiry, CSRF

Links continuation-based session:
  Request 1 โ†’ server runs to first blocking point โ†’ saves continuation
  Request 2 โ†’ server resumes continuation with form data
  Developer manages: nothing. The language handles it.

This eliminates an entire class of session management bugs. It also means that the application's state is always on the EU server โ€” not in a JWT token that could be decoded client-side, not in a cookie that travels to third-party analytics providers.

EU Cyber Resilience Act and Type-Safe Web Applications

The EU Cyber Resilience Act (CRA), in force from 2024, requires that products with digital elements be designed with security by default and security by design. Specifically, it targets:

Links addresses two of these three by construction. A Links application cannot have SQL injection or XSS vulnerabilities because the type system prevents them. This is not a security scanner's finding โ€” it is a mathematical guarantee from the type checker.

For organisations deploying web applications to serve EU customers โ€” subject to GDPR, NIS2, and the CRA โ€” a type-safe tier-unified language directly satisfies regulatory requirements that in other stacks require manual audit, runtime scanning, and security testing infrastructure.

EU Cyber Resilience Act (2024) compliance via Links:

  CRA Article 13(3): "security by design and by default"
    โœ“ Links: type system makes injection/XSS structurally impossible

  GDPR Article 32: "appropriate technical measures"
    โœ“ Links: server-side continuations keep session state in EU

  NIS2 Article 21: "measures to manage cybersecurity risks"
    โœ“ Links: eliminates entire vulnerability classes at compile time

  OWASP Top 10:
    A03 Injection:     โœ“ parameterised queries, structural type safety
    A07 XSS:           โœ“ stringToXml separate from string concatenation
    A02 Cryptographic: neutral (Links doesn't handle crypto)

Links is available as an open-source OCaml application. A Links web server runs as a standard HTTP process and can be containerised with Docker:

# Links application โ€” EU deployment via sota.io
FROM ocaml/opam:ubuntu-22.04-ocaml-4.14

# Install Links
RUN opam install links

# Copy application
WORKDIR /app
COPY --chown=opam:opam . .

# Links server listens on PORT
CMD ["opam", "exec", "--", "linx", "--port=${PORT}", "main.links"]

Deploy to EU infrastructure in 3 minutes:

# Install sota.io CLI
npm install -g sota

# Deploy Links application to Europe
sota deploy --name links-app --region eu-central-1

# Add managed PostgreSQL (GDPR-compliant, EU data residency)
sota db create --name links-db

# Expose database URL to Links runtime
sota env set DATABASE_URL=$(sota db url links-db)

On sota.io, your Links application runs in a European data centre โ€” Germany, Netherlands, or Finland โ€” with data never transiting through US infrastructure. The PostgreSQL database that Links queries is managed, backed up daily, and covered by the same EU data residency guarantee.

The combination is particularly relevant for Links' security model: all computation happens server-side in the EU, all database queries are parameterised and type-safe, and no user data travels to third-party servers.

Links remains an active research language at Edinburgh University and is maintained as an open-source project. It has influenced the design of several subsequent web-oriented languages:

Wadler's insight โ€” that the web's security problems are a consequence of using untyped string interpolation across tier boundaries โ€” has proven correct. XSS and SQL injection remain in OWASP's top ten vulnerabilities year after year, in applications written in languages that did not take the Links approach.

Philip Wadler received the ACM SIGPLAN Programming Languages Achievement Award (2007) and the POPL Most Influential Paper Award. He holds the LFCS Chair (Laboratory for Foundations of Computer Science) at Edinburgh. He was elected a Fellow of the Royal Society of Edinburgh in 2010.

The University of Edinburgh's Informatics programme โ€” home to Links, BCPL's successors, and decades of foundational type theory โ€” is consistently ranked in the world's top five for computer science research.

sota.io is the EU-native PaaS designed for language runtimes like Links:

# Full Links deployment on sota.io
sota deploy --name links-contacts --region eu-central-1
sota db create --name links-contacts-db --region eu-central-1
sota env set DATABASE_URL=$(sota db url links-contacts-db)
sota logs --follow

Philip Wadler's vision โ€” a web programming language that eliminates injection vulnerabilities by construction, keeps session state server-side, and provides type safety across all application tiers โ€” is directly aligned with what EU data sovereignty and the Cyber Resilience Act require from modern web applications.

Deploy Links on EU infrastructure. GDPR-compliant, managed PostgreSQL, zero DevOps.


Philip Wadler ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ is a Professor at The University of Edinburgh, School of Informatics. Links was developed at Edinburgh with Sam Lindley, Ezra Cooper, Jeremy Yallop, and James Cheney. Links is open-source at github.com/links-lang/links.