The Platform

9 products. One codebase.

Every product on this site is built from the same Kotlin Multiplatform SDK and talks to the same API. That constraint is the platform: a fix to authentication, storage or sync reaches all 9 of them at once, on every target.

๐Ÿงฉ

TANVRIT SDK

Identity ยท storage ยท networking ยท design system ยท commerce

Mandee

The counter, the back office, and the books.

Mandee Store

Buy from the shops around you.

Lekhita

เคฒเฅ‡เค–เคฟเคค โ€” written down, recorded.

Friendly

The people nearby, in one place.

Friendly Wedding

Plan a wedding without losing your mind.

School

Attendance, fees, exams โ€” one system.

Tanvrit AI

Your codebase, indexed on your machine.

Auditor

Audit any site. Nothing leaves the browser.

Tanvrit Host

Push a build. Get a URL.

What is actually shared

Not a vague โ€œecosystemโ€ โ€” six concrete layers that every product compiles against.

๐Ÿ”‘

Identity

One auth stack โ€” OTP, email, Google and Apple sign-in โ€” with tokens namespaced per app so a session never leaks across products

๐Ÿ—„๏ธ

Storage

The same offline-first SQLite layer and sync ledger, tenant-scoped on every table

๐Ÿ”Œ

Networking

One typed API client with certificate pinning, retries and a single error envelope

๐ŸŽ›๏ธ

Design system

Shared spacing, shape, elevation and motion tokens, so a fix to a component lands in every app

๐Ÿงพ

Commerce

Catalog, orders, payments and ledger models defined once and reused by the products that need them

๐Ÿšš

Build and release

One version train across core, SDK and every app, with an ABI check that fails the build on a breaking change

How it works

Three steps, from one Kotlin source tree to 9 products on 6 targets.

01

The SDK is written once

Auth, storage, sync, networking, commerce and UI live in 25 Kotlin Multiplatform modules on top of 4 foundation modules. A product depends on the modules it needs and nothing else.

02

It compiles six ways

The same sources produce Android, iOS, JVM desktop, WasmJS, JS and Linux binaries. There is no separate web team and no second implementation to keep in step.

03

One backend serves all of it

A single Ktor 3.5.1 service โ€” 127 feature packages, 270 routers โ€” answers every app. Requests carry an app ID and are scoped to that tenant on the way in.

25

SDK modules

4

Foundation modules

127

Backend feature packages

270

API routers

11,600+

Automated tests

6

Native targets

Why Every Tanvrit Product Is Built on the Same SDK

The usual way to ship an app on four platforms is to write it four times, then spend the rest of its life explaining why the Android version behaves differently from the web one. Tanvrit took the other route: put authentication, storage, sync, networking and the design system into one Kotlin Multiplatform SDK, and make every product compile against it. The cost is paid up front, in a foundation that has to be general enough for a point of sale and a wedding planner at once. What it buys is that a defect fixed in the SDK is fixed everywhere, on every target, in one release.

One Identity Layer, Namespaced Per App

Sign-in is written once โ€” phone OTP, email OTP, Google and Apple โ€” and every product inherits it, along with token refresh, session restore on reload, and secure storage on each platform. Because several products may be installed on the same device, tokens and permission caches are namespaced by application ID rather than shared. A session in the point-of-sale app is not a session in the community app, and a role granted in one cannot leak into the other.

Offline Is the Default Path, Not a Fallback

Reads are served from a local SQLite store before the network is consulted, so a screen renders whether or not there is signal. Writes go into a sync ledger with retry and a dead-letter path for anything that repeatedly fails, and every table is scoped to the tenant that owns it. For a shop in a town where the connection comes and goes through the day, this is the difference between a slow app and an unusable one โ€” and because it lives in the SDK, no individual product has to get it right on its own.

One Backend, One Wire Format

A single Ktor service answers every product. Models are declared once in Kotlin and serialized with the same library on both sides of the wire, which removes the whole category of bugs where a client and server quietly disagree about a field name. Requests carry an application ID and an API key and are scoped to that tenant on the way in. The public surface of the SDK is checked on every push against a recorded baseline, so a change that would break an installed app fails the build rather than a customer's phone.

Platform FAQ

Do I need more than one product to benefit from the platform?
No. Each product is useful on its own. The shared foundation shows up as a consistent sign-in, the same offline behaviour, and โ€” if you do add a second product โ€” an account and customer records that are already there.
Which platforms do the apps run on?
The same Kotlin sources compile to 6 native targets: Android, iOS, JVM desktop, WasmJS, JS and Linux. There is no separate web rewrite, so the browser build is the same application as the phone build.
What is the technical architecture?
Clients are Kotlin Multiplatform with Compose Multiplatform for the interface, built on 25 SDK modules over 4 foundation modules. The backend is a single Ktor 3.5.1 service โ€” 127 feature packages and 270 routers โ€” running on Google Cloud Run in asia-south1 (Mumbai), backed by MongoDB.
How is the platform tested?
There are 11,600+ automated test functions across the foundation modules, the SDK and the server. Lint, static analysis and a binary-compatibility check on the SDK's public API run on every push, and a change that breaks the published surface fails the build.
Can I build custom integrations?
Yes โ€” Enterprise accounts get API access and can connect existing ERP, accounting or third-party tools to the same API the apps use.