WallpaperMachine
The wallpapers you love. A new home on your Mac.
Drop in apartment listing screenshots and see the real monthly cost per person, every fee included. Built with Gemma 4.
LifestyleTypeScript · JavaScriptGitHub @sam044OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
GDG Hackathon VT
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗The rent you see isn't the rent you pay. True Cost uses Gemma 4 to read apartment listings, find every fee, and show what each place really costs per person per month, side by side, before you sign.
Live app: true-cost-xi.vercel.app. Demo video: watch on Loom. Built at GDG Build with AI x Hacktoberfest 2026, Virginia Tech (Oct 24–25, 2026).
True Cost helps students at VT who are looking for off-campus housing see the actual price of housing after all the fees and be able to compare apartments side by side. Our database of over 200 apartments around VT gives VT students plenty of options, and they can sort the database to their liking. Our Chrome extension allows them to, instead, choose an apartment that they like and scan the listing page to find all the fees included and compare it to other apartments in our database.
Blacksburg students pick apartments months ahead, and they compare them by the headline per-bed price. That price leaves a lot out. Admin fees, utility service fees, parking, amenity fees and reconditioning fees sit on separate tabs, in fine print, or in the lease itself. Real examples from Blacksburg listings:
Virginia now requires advertised prices to include mandatory fees (Va. Code § 59.1-608) and leases to itemize charges on the first page (Va. Code § 55.1-1204.1). Few students know that, and nobody adds the numbers up for them. Splitting a unit with roommates makes the math harder still, because some fees are charged per person and some per unit.
You tell it who's splitting, pick or capture up to three apartments, check the fees it found, and get one number per apartment: the true monthly cost per person, with every fee counted.
flowchart TD
subgraph Add["1. Add apartments"]
CAT["Catalog of 143 Blacksburg places<br/>already scanned"]
EXT["Chrome extension<br/>captures any listing page"]
UP["Upload screenshots<br/>or paste text"]
end
EXT -- "stitched screenshots + page text" --> API
UP --> API
API["POST /api/extract<br/>Vercel function"] -- "images + text" --> GEMMA["Gemma 4<br/>gemma-4-26b-a4b-it<br/>fallback gemma-4-31b-it"]
GEMMA -- "record_fees function call:<br/>each fee with its exact quote" --> CHECK["Zod schema + quote and amount checks<br/>unverified fees marked Check this"]
CHECK --> REVIEW
CAT -- "checked by hand" --> COMPARE
CAT -- "auto-scanned, not checked" --> REVIEW
SETUP["2. Setup<br/>people sharing, lease months,<br/>budget, parking / pet / furnished"] --> ENGINE
REVIEW["3. Review fees<br/>edit, delete or add fees,<br/>then Looks right"] --> ENGINE
REVIEW -. "opt-in, anonymous" .-> INDEX[("Blacksburg fee index<br/>Neon Postgres")]
ENGINE["Cost engine + utility estimates<br/>+ Virginia fee rules<br/>plain TypeScript, no AI"] --> COMPARE
COMPARE["4. Compare<br/>true cost per person, advertised vs real,<br/>hidden per year, lease total"]
INDEX -. "fees other students reported" .-> COMPARE
COMPARE --> EMAIL["Leasing-office email<br/>drafted by Gemma 4"]
Everything you enter stays in your browser (localStorage). There are no accounts and screenshots are never stored.
Choose how many people share the unit (1 to 6), how long the lease is, an optional monthly budget per person, and which extras you need (parking, a pet, a furnished unit). Optional fees for the extras you need are counted automatically; the rest are left out.
The Apartments step opens on 143 Blacksburg places whose fees were read ahead of time, so you can compare without adding anything:
Search the list and click a card to add it. Hand-checked places go straight to Compare. Auto-scanned ones open Review first, because nobody has checked their fees yet. Every card shows its source and the date it was read, and links to the original listing.
For a listing that isn't in the catalog, the True Cost extension reads it in one click:
If something fails, the panel says what went wrong and offers Try again. The extension holds no API key and only sends data to the True Cost app. It works in Chrome and other Chromium browsers such as Brave and Edge. Install steps are in extension/README.md.
You can also drop, click or paste up to 5 screenshots, or paste listing text. Images are resized in the browser before they're sent.
POST /api/extract sends the images and text to Gemma 4, which returns structured fees through function calling: name, amount, how often it's charged, whether it's per person or per unit, whether it's required or refundable, and the exact quote it came from. Each quote and amount is checked against the listing. Anything that can't be verified is marked "Check this".
Every fee shows its source quote. Low-confidence fees sort to the top with a "Check this" badge. You can edit any field, delete a fee, add one by hand, or correct the advertised price. Utilities the listing doesn't include get Blacksburg estimates, labelled "Estimate". Numbers only show up after you click Looks right.
One column per apartment, with:
A sentence above the columns gives the answer ("X is $N a month cheaper per person than Y, with every fee counted"), and the cheapest place is highlighted. "See every fee" opens the itemized breakdown, where you can switch fees in or out.
Rules in code (lib/flags.ts) check confirmed fees against Virginia law: advertised prices that leave out mandatory fees (§ 59.1-608), security deposits above two months' rent (§ 55.1-1226), and first-page fee itemization (§ 55.1-1204.1). Each one cites its statute and links to Virginia Law Help. This is information, not legal advice.
One click drafts a polite email to the leasing office that asks for the full fee sheet and turns any Virginia flags into questions rather than accusations. Gemma 4 writes it. If Gemma fails, or the draft mentions an amount it wasn't given, a plain template is used instead. The To line is filled in only when the listing shows the office's email. Copy it, or open it in Gmail, Outlook or your mail app.
If you tick the box on Review (it's off by default), the fees you confirmed are shared anonymously: only the complex name and the fee amounts. Compare then shows fees other students reported at the same complex that aren't on your list, such as "Utility service fee, $62/month, reported 3 times". It stores only fees a person has checked, never raw model output, images, quotes or anything about you. Rate limiting uses a hash that changes daily, so submissions can't be linked across days.
gemma-4-26b-a4b-it (fallback gemma-4-31b-it) through the Gemini API, using the @google/genai SDK.record_fees function with the exact quote for each, and drafts the leasing-office email.lib/cost.ts and lib/flags.ts does both.prefers-reduced-motion.npm run eval scores extraction on 8 hand-labelled Blacksburg listings in eval/cases/ and writes eval/results.json. Latest run: 100% precision and 100% recall (33 of 33 fees, no extras), advertised price right on 8 of 8.
npm install
cp .env.example .env.local # then paste your key from https://aistudio.google.com
npm run dev # http://localhost:3000
npm test # unit tests
npm run eval # extraction eval
GEMINI_API_KEY is required. DATABASE_URL (Neon Postgres) is only needed for the fee index; without it the app still works and the index section stays hidden.
Next.js 15 (App Router), TypeScript, Tailwind CSS v4, shadcn/ui, Zustand, Zod, Gemma 4 through @google/genai, Neon Postgres, deployed on Vercel. The extension is a Manifest V3 Chrome extension with a side panel.
Sam (@sam044) and Andy (@andyshah17).