DEV Community

Munni Moni
Munni Moni

Posted on

Building a State-Specific Landlord-Tenant Law Database with React

Why I Built a State-Specific Legal Database

When I started building LeaseLenses — a free AI tool for analyzing lease agreements — I quickly realized the biggest challenge wasn't AI. It was the law itself.

Landlord-tenant law varies wildly across all 50 US states. What's legal in Texas might be illegal in California. A security deposit limit in New York is completely different from Florida.

The Data Model

Here's the TypeScript interface I designed:

\typescript
interface StateLaw {
state: string;
stateCode: string;
securityDeposit: {
maxMonths: number | null; // null = no limit
interestRequired: boolean;
returnDays: number;
itemizedDeductions: boolean;
};
eviction: {
nonPaymentNoticeDays: number;
cureOrQuitDays: number | null;
unconditionalQuitDays: number | null;
courtRequired: boolean; // always true in US
};
leaseTermination: {
monthToMonthNoticeDays: number;
militaryExemption: boolean; // SCRA
domesticViolence: boolean;
habitabilityBreach: boolean;
};
landlordEntry: {
noticeDays: number;
emergencyException: boolean;
tenantCanRefuse: boolean;
};
lateFees: {
maxPercentage: number | null;
gracePeriodDays: number;
};
}
\
\

Example: California vs Texas

\`typescript
const california: StateLaw = {
state: 'California',
stateCode: 'CA',
securityDeposit: {
maxMonths: 1, // As of 2024, 1 month max
interestRequired: false,
returnDays: 21,
itemizedDeductions: true,
},
eviction: {
nonPaymentNoticeDays: 3,
cureOrQuitDays: 3,
unconditionalQuitDays: null,
courtRequired: true,
},
leaseTermination: {
monthToMonthNoticeDays: 30,
militaryExemption: true,
domesticViolence: true,
habitabilityBreach: true,
},
landlordEntry: {
noticeDays: 1, // 24 hours
emergencyException: true,
tenantCanRefuse: true,
},
lateFees: {
maxPercentage: null, // Must be "reasonable"
gracePeriodDays: 0,
},
};

const texas: StateLaw = {
state: 'Texas',
stateCode: 'TX',
securityDeposit: {
maxMonths: null, // No statutory limit!
interestRequired: false,
returnDays: 30,
itemizedDeductions: true,
},
eviction: {
nonPaymentNoticeDays: 3,
cureOrQuitDays: null, // No cure period
unconditionalQuitDays: 3,
courtRequired: true,
},
leaseTermination: {
monthToMonthNoticeDays: 30,
militaryExemption: true,
domesticViolence: true,
habitabilityBreach: true,
},
landlordEntry: {
noticeDays: 0, // No statutory requirement!
emergencyException: true,
tenantCanRefuse: false,
},
lateFees: {
maxPercentage: null,
gracePeriodDays: 0,
},
};
`\

The React Hook

\`typescript
function useStateLaw(stateCode: string) {
const [law, setLaw] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
async function fetchLaw() {
try {
const response = await fetch(
`/api/laws/\${stateCode}`
);
const data = await response.json();
setLaw(data);
} catch (err) {
console.error('Failed to load state law:', err);
} finally {
setLoading(false);
}
}
fetchLaw();
}, [stateCode]);

return { law, loading };
}
`\

Compliance Checker Component

\`tsx
function LeaseComplianceChecker({
lease,
stateCode
}: Props) {
const { law, loading } = useStateLaw(stateCode);

if (loading || !law) return ;

const violations = [];

// Check security deposit
if (law.securityDeposit.maxMonths &&
lease.depositMonths > law.securityDeposit.maxMonths) {
violations.push({
severity: 'high',
message: `Security deposit exceeds \${law.state} limit of \${law.securityDeposit.maxMonths} month(s)`,
});
}

// Check entry notice
if (law.landlordEntry.noticeDays > 0 &&
!lease.hasEntryNoticeClause) {
violations.push({
severity: 'medium',
message: `\${law.state} requires \${law.landlordEntry.noticeDays * 24} hour notice for entry`,
});
}

return (


{violations.map((v, i) => (

{v.message}

))}

);
}
`\

Lessons Learned

  1. Legal data needs constant updates — Laws change annually
  2. Edge cases are everywhere — City-level ordinances override state laws
  3. "No limit" doesn't mean "anything goes" — Courts enforce "reasonableness"
  4. Structured data beats free text — JSON schemas enable programmatic validation

Resources


What legal/regulatory data challenges have you tackled in your projects? I'd love to hear your approaches!

Top comments (0)