Product architecture
Hearth
A cross-platform home-maintenance application designed to help homeowners understand, maintain, and preserve the long-term history of their home.
- React Native
- Expo SDK 57
- Expo Router
- Node.js
- TypeScript
- Supabase
- PostgreSQL
- Cloudflare R2
The ownership container for members, components, documents, history, and access rules.
Ownership · Access isolation · Server-held secrets · Shared work history
01 / Context
What it solves
Home ownership creates a long trail of disconnected information: appliances, maintenance schedules, warranties, contractor details, costs, risks, and documents. Important context is often scattered across email, paper records, calendars, and memory.
Hearth is intended to make that information useful as a system rather than another collection of notes. Its focus is structured ownership and maintenance—not generic DIY content or an open-ended AI chat experience.
Why I rebuilt Hearth
I built the first version quickly with heavy Cursor assistance. That helped me move fast, but the result accumulated architectural and implementation issues. Before adding more features, I needed to revisit the foundation.
The rebuild focuses on better domain modeling, clearer data ownership, and fewer fragile shortcuts. I want the app to stay simple and inexpensive as it grows, without every new feature making the underlying model harder to maintain.
02 / Product shape
A durable ownership loop
The product is organized around a repeating sequence that becomes more valuable as the home history grows.
- 01Set up the home
- 02Understand its assets and components
- 03See what needs attention
- 04Record completed work
- 05Preserve documents, costs, warranties, and contractors
- 06Build a durable history of the home
03 / Requirements
What the system needs to handle
- Work across iOS and Android without maintaining two independent products.
- Let homeowners begin with limited information and enrich their records over time.
- Keep home data isolated according to membership and access rules.
- Preserve maintenance history while making deletion behavior understandable.
- Support documents and flexible home attributes without weakening the core relational model.
- Leave room for reminders, seasonal intelligence, risk scoring, and carefully scoped AI-assisted insights.
04 / Architecture
Engineering decisions
One component model instead of a table for every appliance
I moved toward a stable home_components model with flexible attributes, plus generic work_records for maintenance and history. A dishwasher and an HVAC system have different details, but both belong to a home and need records of work done on them. That shared structure belongs in the core model.
Alternative considered. Separate tables and schemas for HVAC, dishwashers, roofs, and other component types would make each type explicit. I rejected that direction because new types and attributes would keep creating schema changes and migrations.
Trade-off. Flexible attributes reduce structural churn, but they still need clear validation rules. Relational columns retain ownership and shared relationships; flexibility should cover the details that vary, rather than turn the entire record into an unstructured document.
Keep trusted work on the server
React Native and Expo handle the mobile experience, while Supabase and PostgreSQL provide the data foundation. The Node/TypeScript backend is reserved for AI, jobs, secrets, and other logic that should not live in the client. The boundary follows what the operation needs to protect.
Trade-off. A separate backend adds deployment and maintenance work. Keeping its responsibility focused limits that cost while giving privileged operations a place outside the mobile application.
Derived history instead of duplicated totals
Work records form the source of truth for completed maintenance and cost history. Spending summaries and timelines can be derived from those records, avoiding redundant values that could drift out of sync.
Let the home record grow gradually
A homeowner should not need a complete inventory on day one. The product is centered on the home, with components, work records, contractors, warranties, documents, and costs building up its history over time. Keeping those concepts stable gives new workflows a foundation to build on.
05 / Trust
Reliability and privacy
Home records are personal and long-lived. Their access and lifecycle need to be understandable, not hidden behind product language.
Home-owned access
The current architecture uses authenticated ownership checks around the home/user relationship. Signing in identifies the user; the ownership check establishes whether that user may access the requested home's data. Both matter when records are organized around a shared domain entity.
Planned deletion lifecycle
The intended deletion flow includes soft deletion, a 30-day grace period, a clear purge date, and immediate session revocation. This remains a design goal here, rather than a claim that the full lifecycle has been implemented and verified.
Documents as sensitive data
Warranties, invoices, contractor information, and home details can reveal more than ordinary app content. Cloudflare R2 stores document objects separately, while database records retain ownership and metadata needed to authorize access.
Plain-language failures
Errors should tell homeowners what happened and what they can do next. This matters especially for uploads, account access, and destructive actions where vague failures can damage trust.
06 / Reasoning
Trade-offs
- Supabase handles much of the backend foundation, while Node/TypeScript provides a focused boundary for trusted work. That keeps the architecture relatively small, but still leaves two places whose access rules and responsibilities need to stay clear.
- A component-specific schema makes database constraints more explicit. A shared model makes new types easier to add, but requires deliberate rules for validating and querying flexible attributes.
- Derived totals reduce consistency problems, though expensive summaries may eventually need measured caching or precomputation as real usage grows.
- A cross-platform application increases product consistency and development leverage, while some device-specific behavior may still require platform-aware implementation.
07 / Status
Current status
Working today: a cross-platform home-management app built with React Native/Expo, Supabase/PostgreSQL, and a Node/TypeScript backend. The core is organized around homes, components, work records, contractors, warranties, documents, costs, and history, with authenticated ownership checks around the home/user relationship.
In the rebuild: a more stable component model, clearer data ownership, and fewer fragile shortcuts. The aim is a foundation that remains understandable as the product grows.
Planned expansion: reminders, seasonal intelligence, scoring, and AI-assisted insights. Reserving backend responsibilities for AI and jobs does not mean every planned feature is already built.
08 / Reflection
What the rebuild is reinforcing
- AI-assisted development helped me build quickly, but reviewing the architecture and implementation remained my responsibility.
- Model the shared behavior first. Different appliances need different attributes, but that does not automatically mean they need different tables.
- Flexibility moves some work from schema changes into validation. It needs boundaries of its own.
- A simple architecture still needs explicit ownership and a clear place for trusted server logic.
09 / Related writing
The reasoning behind the rebuild
Why I Prefer Simple Architectures First
Complexity is sometimes necessary, but it should arrive with evidence about the problem it is solving and the cost the team is accepting.
Read article