Delivered engagementHealth & Wellness · $35k – $40k+
Läkare (Familjeläkaren)

Läkare.se · Swedish telemedicine platform

Delivered engagement. Coralsoft designed and built this product end to end; figures below retain their evidence level.

MobileWebBackendNext.js 16 (App Router)React 19oRPC + TanStack Query
lakare-telemedicine-platform.example / dashboard
Läkare doctor console (Patientliggaren) — Drop-In, Checkarna, Mina Aktuella and Osignerade queue tabs with a table of signed consultations by patient, contact reason, sign time and doctor
The situation

What was in place before we started.

Läkare is a Swedish telemedicine platform connecting patients with doctors for remote care — drop-in consultations, prescription renewals, medical certificates, and specialist referrals — rebuilt full-stack from a Spring Boot monolith onto Bun, Hono, oRPC, Drizzle, and PostgreSQL, with a from-scratch BankID implementation and an idempotent Webdoc EHR integration.

Läkare is a Swedish telemedicine platform connecting patients with doctors for remote care: drop-in consultations, prescription renewals, medical certificates, and specialist referrals. It serves two audiences from one system — patients requesting care through a web platform and a native mobile app, and doctors/clinic staff triaging, claiming, and resolving those requests through a shared real-time queue, chat, and clinical documentation workflow.

Operating inside the Swedish healthcare system means integrating with two pieces of infrastructure that don’t exist in most other markets: BankID, Sweden’s national electronic ID scheme used for authentication instead of passwords or OAuth for the vast majority of users, and Webdoc, a third-party EHR that clinics use as their system of record — every doctor-signed consultation gets written into Webdoc as a real clinical journal entry, not just stored in Läkare’s own database.

Constraint

As the product’s scope grew, the Java backend became the bottleneck for iteration speed. We rebuilt the backend from scratch as a modular, ports-and-adapters (“hexagonal”) monolith on Bun, Hono, oRPC, Drizzle, and PostgreSQL, replacing the traditional MVC layering entirely.

Timeline
8 months reconstructed
Team
6 people reconstructed
Budget
$35k – $40k+ reconstructed
Platforms
3
Stackrecorded
Next.js 16 (App Router)React 19oRPC + TanStack QueryTailwind CSS v4Expo SDK 54 / React Native 0.81Expo Router v6Redux ToolkitBun runtime (WebSockets, TLS, crypto)HonooRPC (typed RPC + OpenAPI)Drizzle ORM + PostgreSQLBetter Auth (+ custom BankID plugin)S3-compatible storage (MinIO in dev)puppeteer-core (PDF rendering)Zod
Challenges

Each constraint, and what we did about it.

Constraint

As the product’s scope grew, the Java backend became the bottleneck for iteration speed. We rebuilt the backend from scratch as a modular, ports-and-adapters (“hexagonal”) monolith on Bun, Hono, oRPC, Drizzle, and PostgreSQL, replacing the traditional MVC layering entirely.

What we did

The backend is a modular monolith with an explicit hexagonal composition root: a small app/ composition root wires the server and router, a routers/ layer aggregates around 14 domain routers into one typed router, modules/ holds one folder per bounded context, platform/ holds infrastructure adapters, and shared/ holds cross-module pure helpers. The composition root instantiates every infrastructure adapter exactly once as a port-typed singleton, then wires each application service with only the ports it actually needs — there’s no DI framework; dependency injection happens through plain closures, which keeps every service’s true dependency surface visible and trivially mockable in tests.

Results

Outcome, with the source of every figure.

9,300
Lines of Java monolith replaced by a modular TypeScript backend
self-reportedCoralsoft's own figure for its own delivery, stated in cases.ts. No third-party attestation in the sources.
~15
Config-driven Checkarna self-triage checks sharing two engines
self-reportedCoralsoft's own figure for its own delivery, stated in cases.ts. No third-party attestation in the sources.
3
Codebases — backend, web, and mobile — sharing one typed oRPC router and one clinical-rules package
self-reportedCoralsoft's own figure for its own delivery, stated in cases.ts. No third-party attestation in the sources.
Showcase

How the system fits together.

2 of 2 views
lakare-telemedicine-platform.example
Läkare consultation view — patient header with vitals, a doctor–patient chat panel, and a clinical journal with allergies, diagnoses, medications and anamnesis, plus add-certificate and add-referral actions
lakare-telemedicine-platform.example
Läkare certificate generator — a dialog to choose a Swedish or English certificate type, booking date and diagnosis before generating the PDF
Roadmap

How it was sequenced.

8 monthsreconstructed delivery
Months 1–2

Discovery & architecture

A full backend rewrite: Spring Boot/MySQL → Bun/Hono/oRPC/Drizzle/PostgreSQL, replacing the traditional MVC layering with a ports-and-adapters monolith.

  • Backend rewrite
Months 3–4

Core build

A custom Better Auth plugin implementing Sweden’s BankID protocol from scratch — mutual-TLS relying-party client, QR code generation, encrypted server-side transaction state, per-browser/per-device deep-link handling.

  • BankID from scratch
Months 5–6

Integrations & data

A production integration with Webdoc, including a compare-and-swap idempotency mechanism that makes a multi-step external booking→visit→sign workflow safely resumable across retries and crashes.

  • Webdoc EHR integration
Month 7

Hardening & QA

A real-time doctor queue and chat system built on raw Bun WebSockets, with no third-party realtime service, shared across web and mobile.

  • Real-time queue & chat
Month 8

Launch & handover

Doctors author, autosave, and sign clinical records, with the sign/resign business rules extracted into a single framework-free, unit-tested package shared by both frontends.

  • Signing-journal workflow

More work like this.

Every case study is a Coralsoft delivery story, with the evidence behind each figure kept visible.