Technology

Boring choices, made deliberately

Nothing in this stack is novel, and that is the point. A lending platform should be built from technologies your next engineer already knows, so that the interesting part is the domain rather than the tooling.

The stack

Four surfaces, one language

  • Next.js

    The marketing site and the operations console. App Router, server components by default, minimal client JavaScript.

  • Expo React Native

    The borrower app for iOS and Android from one codebase, on the current SDK with the new architecture.

  • Node & Express

    The API and the system of record. Unremarkable, well understood, easy to hire for.

  • MongoDB

    Document storage with typed schemas, and hooks that enforce the regulatory invariants at the data layer.

One language

TypeScript in strict mode, everywhere

The same language across the API, the console and the mobile app is not about developer preference. It is what allows the regulatory constants and the domain types to be literally shared rather than reimplemented three times.

  • Strict mode with no implicit any and checked index access
  • Regulatory constants, domain types and validation schemas in one shared layer
  • A limit cannot mean one thing on the server and another in the app
  • A typo in a content file or an illustration reference is a compile error, not a blank page

Shared contracts

One definition, copied deliberately, verified in CI

The applications are independent projects with their own deployment cadence, so they cannot import from each other. The shared layer has a single canonical home and is copied into each client by a script, with drift caught before it ships.

  • One canonical source for constants, types and schemas
  • Copies marked read-only and excluded from version control
  • A check mode that fails the build if any copy has diverged
  • The shared layer depends on nothing — no server framework, no UI library

Boundaries

Nothing unvalidated reaches a model

Schema validation runs at every API boundary and the parsed value replaces the raw request data, so there is no code path where an unchecked field can reach the database.

  • Schemas shared between the API and the clients, so both agree on what is valid
  • Money accepted only as a non-negative integer in paisa — floats are rejected, not rounded
  • Nepali mobile numbers validated to the real format, not a generic phone pattern
  • Free text sanitised of control characters before storage
no bypass exists

Testing

The compliance paths are the ones under test

Full coverage everywhere is a slogan. Deep coverage of the code that can produce an unlawful loan is a control. The tests that matter assert that the limits hold and the state machine has no shortcut.

  • Loan ceilings tested at, above and below each boundary
  • Tenure cap tested at 36 and 37 months
  • A test that walks every route through the state graph and asserts each passes KYC review
  • A red test on any of these blocks the release

Performance

Built for a mid-range Android on a slow connection

The borrower is not on a flagship phone on fibre. This site itself is the demonstration — every animation on it is CSS, and there is no animation runtime in the bundle.

  • Server components by default; client JavaScript only where interaction requires it
  • All illustrations are inline SVG animated with CSS — no animation library
  • Motion driven entirely by CSS, so one media query honours reduced-motion everywhere
  • Modest data footprint in the mobile app, which matters when the borrower pays for it

Operations

How it is run

  • Structured logging

    JSON logs with a redaction list, and a request id that ties a support ticket to its audit entries.

  • Fail fast on config

    The process refuses to boot on an invalid environment, and refuses production with a mock vendor or an echoed OTP.

  • Graceful shutdown

    In-flight requests drain before exit, so a deploy never cuts a write mid-transaction.

  • Scripted operations

    Setup, checks and key rotation are reviewed scripts, not commands in somebody’s shell history.

  • Vendor interfaces

    KYC, SMS and payments behind interfaces with mock drivers. Nothing real is wired without a recorded decision.

  • Documented decisions

    Architectural decisions recorded and numbered, including the ones we later changed our mind about.

Coming soon

Bring your architects

The technical walkthrough is the part we enjoy most. Send the people who will ask the hardest questions.