Skip to main content
Distributed Systems

Neo Learn — SMS as a Transport Layer

A systems experiment in treating SMS and SIM Toolkit as transport mechanisms rather than the application itself — course progress, assessment state and submissions live centrally, and the learner reaches that state through web, mobile, SMS or STK without the learning engine ever knowing which interface was used.

Engineering ProjectActive design, experimental side projectTags: Offline-First, SMS / SIM Toolkit, Idempotency
Context

What was happening.

An offline-capable learning platform that keeps a modern web and mobile experience while retaining SMS and SIM Toolkit as a fallback communication layer. Same learning state, different interface, depending on what connectivity is available.

The problem

What needed to change.

  • A conventional online learning platform assumes connectivity: when the internet disappears, the learning experience stops entirely.
  • Text-message learning survives disconnection, but a purely conversational interface is cumbersome for richer course structures, progress tracking, assessments and larger amounts of content.
  • SMS is asynchronous and unreliable as a delivery channel — duplicate, out-of-order, delayed and failed messages are the norm rather than the exception.
  • The same learner action arriving over two very different interfaces makes the application a synchronization problem as much as an education problem.
The approach

How it was done.

Transport abstraction

SMS and SIM Toolkit are treated as transports, not as the application. Course progress, assessment state, submissions and account information live centrally in the platform; the learner reaches that state through different interfaces — a rich web or mobile experience when connected, SMS lessons and multiple-choice assessments when not, and STK interactions where supported. Both operate against the same learner and course state.

Two interfaces, one platform — the interface changes, the learning state does not
Transport pipeline

A learning event enters a message queue, then a transport router selects the delivery channel. Adding a channel means adding a transport, not rewriting the learning engine — candidate transports include web, Android, SMS, SIM Toolkit, WhatsApp, email and push. The engine only ever needs to process the learner's action.

Adding a channel means adding a transport, not rewriting the learning engine
Unified learning state

Consistency across interfaces is the central engineering problem. Lesson 4, question 1, answer B, correct, 42% progress is the same record whether it came from a React interface or an SMS reply. A learner can start a lesson in the app, lose connectivity, receive the next question by SMS, reply, then reconnect and see updated progress.

One learner action, one record — whichever interface it arrived through
Offline-first sync

The client caches course metadata, downloaded lessons, assessments, profile information and progress state. Actions taken offline enter a local store and sync queue; once connectivity returns they flow through the backend and conflict resolution into synced state. SMS provides a second path for actions that cannot wait for a connection.

Offline actions queue locally, then resolve conflicts on reconnect
Idempotent message processing

Because SMS is asynchronous, the messaging layer is treated as a distributed system and must account for delivery delays, duplicate and out-of-order messages, failed delivery, retries and expiry. Each response is reduced to a message ID and checked against processed events: a learner who sends the same answer twice because no acknowledgement arrived is never scored twice.

A learner who taps send twice is scored once
Multi-tenant teacher & admin platform

A dedicated educator interface covers course and lesson creation, assignment, class management, progress monitoring, result review and identifying learners falling behind — without caring which interface a student completed a lesson through. An administrative layer adds institution-level controls: accounts, permissions, messaging statistics, delivery status, usage analytics and system health.

Institution-level controls with role-scoped access
Measured results

The numbers that came out.

Same
Interfaces, one record

Web, mobile, SMS and STK all resolve to the same learner action.

7+
Transport layers

Web, Android, SMS, STK, WhatsApp, email and push as candidate transports.

Prevented
Double-scoring

Message IDs checked against processed events before any answer is applied.

Design
Status

Under active design, experimental side project — no working implementation yet.

Outcomes

Where it landed.

  • Demonstrates that SMS can function as a transport layer for a modern learning platform rather than as the platform itself.
  • Separates learning state from communication transport — the interface changes with connectivity, the underlying record does not.
  • Treats an unreliable asynchronous channel as a distributed system: idempotency, retries, deduplication and expiry are designed in rather than bolted on.
  • Offline actions queue locally and resolve conflicts on reconnect, with SMS as the fallback when an action genuinely cannot wait.
Stack & tools
TypeScriptReact / Next.jsPWA / IndexedDBGo or PythonREST APIPostgreSQLRedis (queues)SMS GatewaySIM Toolkit (STK)DockerCI/CD
Start a conversation

Your situation probably looks different — but the method doesn't.

Understand the work, decide the approach, deliver and measure. A free conversation establishes whether it applies to your problem.

or email joseph.gitau.c@gmail.com