arm
  • Home
  • Work
  • About
  • Writing
  • Resume
  • Contact
Open to work
❡Case study · Deep dive · 8 min read

CareKit — one codebase that becomes four different products.

A single config file turns the same app into PetCare, ChildCare, AutoCare, or BikeCare.

conceptplatformplatformconfig-drivenconcept
White-label, driven by one file
CareKit is a config-driven platform: a single serviceConfig.ts decides terminology, feature flags, and theme, and the whole product re-skins itself around a new vertical. Build the booking-and-billing engine once, ship it as four brands.
4
Verticals
1
Config file
1
Codebase
∞
Themes possible
Same app, two brands

§01The problem

“Booking + customers + payments” is the same software whether the thing being cared for is a pet, a child, a car, or a bike. Rebuilding it per vertical is wasted work; forking it per client is a maintenance trap where every bug fix has to be applied N times.

The bet: express everything that differs between verticals as data, and keep the engine identical. One bug fix, four products improved.

§02System architecture

The architecture is the config boundary. Anything vertical-specific — labels, enabled features, colours — is data; everything else is shared engine code that never knows which brand it is running as.

Config
serviceConfig.tsTerminology mapFeature flagsCSS theme tokens
Client
Next.js 15Config-aware componentsTailwind v4 themes
API
HonoDrizzle
Commerce
RazorpayResend (email)

§03Three decisions worth defending

Decision 01

One config object as the seam

Every vertical difference funnels through serviceConfig.ts. Components read terminology and flags from it rather than hard-coding “pet” or “child” — so a new vertical is a new config, not a new branch.

Decision 02

Theme via CSS variables, not rebuilds

Each brand is a set of CSS-variable tokens, so re-skinning is runtime, not a separate build. The same lesson powers this portfolio's twelve palettes.

Decision 03

Feature flags over forks

BikeCare might not need vaccination reminders; ChildCare does. Flags in the config switch whole features on and off so the codebase stays singular instead of splintering per client.

§04Hardest problems, plainly

Challenge 01

Finding the right abstraction line

Abstract too little and every vertical needs code changes; abstract too much and the config becomes a second programming language. Drawing that line is the entire design problem.

Challenge 02

Type-safe terminology

If a component asks the config for a label that a vertical forgot to define, that should be a compile error, not a blank string in production. Keeping the terminology map fully typed is what makes the pattern safe.

Challenge 03

Avoiding config sprawl

Every new toggle is tempting to add to the config. Without discipline it balloons into an unreadable mega-object — so the bar for “does this truly differ per vertical?” has to stay high.

“Write the engine once, describe the product as data. The hard part is deciding what counts as data.”— Parm, on CareKit
Talk about this project →
Open to work

Have something in mind? Let's make it.

iamparmjeetmishra@gmail.com→
GithubMailLinkedInX/Twitter
arm© 2026 — Made with ♡ by Parm
HomeWorkAboutWritingResumeContact