← All projects

JustCar: Smart Car Comparison Platform

Cover Image for JustCar: Smart Car Comparison Platform

The problem

Buying a car means visiting dozens of websites. Manufacturer sites show specs differently. Regional pricing varies wildly. Comparing a Toyota to a Honda means opening multiple tabs and manually cross referencing data that doesn't quite match up.

I wanted to compare cars the same way I'd compare laptops on a spec comparison site. Side by side, with consistent data points, across different markets. That platform didn't exist.

What I built

JustCar aggregates data from 49,000+ vehicles across 219 brands. Users can compare up to 4 cars side by side with 50+ specifications, filter by body type, and see pricing across multiple markets including Vietnam, Philippines, Japan, UK, India, Australia, Singapore, EU, and Canada.

The journey

I thought the hard part would be building scrapers. I was wrong. Scraping was straightforward. The real challenge was making sense of data that was never meant to be compared.

Tech stack

Layer Technology Why
Frontend Next.js 16 App Router, ISR for SEO
Language TypeScript Type safety for complex data
Database Supabase PostgreSQL with full text search
Validation Zod Runtime schema validation
Styling Tailwind CSS 4 Utility first, fast iteration
Hosting Vercel Edge caching, easy deploys

What building this taught me

1. Data quality is the product

I spent 70% of my time on data cleaning and normalization, 30% on the UI. Users don't care about your beautiful interface if the specs are wrong.

One site lists horsepower as "300 hp," another as "300HP," another as "224 kW." Engine displacement might be "2.0L" or "1998cc" or "2000 cm³." Making these comparable required building a normalization pipeline more complex than the UI itself.

// Real example of variations I had to handle
const horsepowerVariations = [
  '300 hp',
  '300HP',
  '300 bhp',
  '300ps',
  '224 kW',
  '223.71kW',
  '224kw',
]

// Normalized to:
interface NormalizedPower {
  value: number // 300
  unit: 'hp' // standardized
  kw: number // 224 (always include kW conversion)
}

Resources that helped:

2. Scrapers are never done

I thought: build scraper, run scraper, done. Reality: websites change constantly.

A site redesigns, your scraper breaks. A site adds anti bot measures, your scraper breaks. A site changes their data format, your scraper breaks.

I learned to treat scraper maintenance as ongoing work, not a one time setup. I built monitoring with Sentry so I know within hours when something breaks.

Scraper Health Dashboard:
┌────────────────┬────────┬──────────┐
│ Source         │ Status │ Last Run │
├────────────────┼────────┼──────────┤
│ AutoTrader UK  │ ✓      │ 2h ago   │
│ CarGurus       │ ✓      │ 3h ago   │
│ AutoData PH    │ ⚠      │ 1d ago   │ ← needs attention
│ CarQuery API   │ ✓      │ 6h ago   │
└────────────────┴────────┴──────────┘

3. PostgreSQL full text search is underrated

I almost added Elasticsearch because that's what "real" search uses. Then I tried PostgreSQL's built in full text search with trigram indexes.

It handled 49,000+ records beautifully. The realization: sometimes the boring choice is the right choice. Not everything needs a specialized tool.

-- PostgreSQL trigram search that replaced Elasticsearch
CREATE INDEX idx_cars_search ON cars
USING gin (name gin_trgm_ops, brand gin_trgm_ops);

-- Fast fuzzy search
SELECT * FROM cars
WHERE name % 'camery'  -- finds "Camry" despite typo
ORDER BY similarity(name, 'camery') DESC;

Resources:

4. Multi market complexity compounds

A "base model" in one market might have features that are "premium" elsewhere. The same car might have different names in different regions. Prices in different currencies need conversion but also contextual understanding.

Is $30,000 expensive for this car? Depends on the market. This complexity kept revealing itself in layers.

The bigger realization

Building JustCar taught me that aggregation products live and die by data quality. I could have built the world's best UI, but if users find one wrong spec, they lose trust in everything.

The unsexy work of validation, cleaning, and monitoring is what makes the product valuable. Features are easy. Trustworthy data is hard.

What I would do differently

Build an admin dashboard from day one. I managed data through scripts and direct database queries for months. A proper admin interface for reviewing flagged data, fixing issues, and monitoring scraper health would have saved hours of terminal work every week.

References

Links

Let's build something together.

Got an idea? I'm always up for a new challenge, whether it's a side project, a startup, or something in between.

© 2026 Cyrus David Pastelero. All rights reserved.

Built with Next.js, TypeScript & Tailwind CSS