Stack Selection

ADR:2 - Technology Stack Selection

1. Context & Problem Statement

The platform must operate smoothly on-premise within a Level 4 facility in Western Kenya. The technology stack must meet specific operational criteria:

  • High Development Velocity: The engineering team must quickly implement complex local billing and statutory regulatory changes (such as the NHIF to SHA transition).
  • Resource Efficiency: The backend and frontend run on local, resource-constrained server hardware, requiring minimal memory and CPU overhead.
  • Maintainability & Type Safety: Cross-module data flows must be explicit, typed, and straightforward to debug without complex microservice monitoring tools.
  • Resilient Package Management: Local deployment workflows must work reliably despite unstable internet connections.

2. Technology Stack & Selection Rationale

The technology stack was selected to maximize performance and maintainability while respecting our local infrastructure constraints.

Rendering Chart

2.1 Frontend: Nuxt 4 and Bun Monorepo

  • Single Page Application (SPA) Mode: The interface is configured to build as an optimized SPA. This design ensures that once client terminals load the primary asset bundle, view transitions occur completely client-side. This keeps the UI responsive even if local Wi-Fi connections experience brief drops.
  • Tailwind CSS Ecosystem: Provides an accessible, responsive set of components optimized for data-dense clinical and financial layouts.
  • Bun for Monorepo Lifecycle Management: Bun replaces npm/yarn as our package manager and workspace execution engine. It cuts local production dependency install times significantly and drastically reduces local bundle compilation lag.

2.2 Backend: Python, Django, and Django Ninja

  • Python Stability: Python provides a mature ecosystem for healthcare informatics, with native libraries for parsing legacy medical device streams (ASTM/HL7) and handling secure field-level encryption routines.
  • Django as a Modular Framework: Django provides an established Object-Relational Mapper (ORM), secure session middleware, and database migration tooling out of the box, ensuring data consistency across modules.
  • Django Ninja (Type-Safe APIs): Django Ninja uses Python type hints and Pydantic v2 to automate request validation and OpenAPI document generation. It achieves execution performance comparable to FastAPI while preserving access to Django's ecosystem:
# Django Ninja execution performance paradigm
from ninja import Router
from pydantic import BaseModel, Field
import uuid

router = Router(tags=["Triage Core"])

class TriageVitalsIn(BaseModel):
    patient_id: uuid.UUID
    systolic_bp: int = Field(..., ge=40, le=250)
    diastolic_bp: int = Field(..., ge=20, le=150)
    temperature_celsius: float = Field(..., ge=32.0, le=43.0)

@router.post("/vitals", response={201: dict})
def commit_triage_vitals(request, payload: TriageVitalsIn):
    """
    High-performance API route leveraging explicit Pydantic type validation
    before executing the underlying database operation.
    """
    # Type integrity is verified automatically before executing this block
    from apps.clinical.services import register_triage_event
    result = register_triage_event(payload.dict())
    return 201, {"status": "SUCCESS", "mews_score": result.mews_score}

2.3 Package Management: uv

The backend development and deployment pipeline uses Astral's uv package manager written in Rust.

  • Offline Deployment Resilience: In regional deployments where internet connectivity can be slow or unstable, uv installs python dependencies significantly faster than standard pip and maintains a reliable local wheel cache. This ensures deployment scripts run predictably during maintenance windows.

2.4 Database, Caching & Task Processing: PostgreSQL, Redis, and Huey

  • PostgreSQL 18: Serves as our primary transactional database, chosen for its strong support for relational integrity, native table partitioning, high-performance JSONB data types for laboratory data, and robust ACID compliance for financial tracking.
  • Redis: Acts as a high-performance, in-memory data store, handling real-time cache lookups, web session validation vectors, and serving as the message transport broker for backend events.
  • Huey (Lightweight Event-Driven Architecture): The system uses Huey instead of Celery for background task management. Celery introduces considerable configuration overhead and requires a complex multi-container setup. Huey provides a lightweight, thread-safe background execution engine that integrates directly with Django and Redis, handling asynchronous tasks with minimal CPU and memory consumption.

3. Technology Evaluation Matrix

Vector CriterionRejected ParadigmSelected Architecture
Package Managementpip / pipenv (Slow resolutions, network failure prone)uv (Rust-backed, rapid, robust local caching)
API ArchitectureDjango REST Framework (Verbose serializers, slower serialization)Django Ninja (Pydantic-backed, type-safe, lower latency)
Background ProcessingCelery + RabbitMQ (Heavy memory usage, complex configuration)Huey + Redis (Minimal resource footprint, reliable)
Frontend RuntimeNode.js / npm (Slower build speeds, larger memory usage)Bun (Fast execution, optimized monorepo support)

ADR Sign-Off Block

Document Reference: ADR-0002-STACK-SELECTIONApprover: Ian Wataka - Backend DeveloperDate Approved: June 22, 2026