Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Check HDB resale prices, condo transaction history, and fair market value for any Singapore property. Free tool powered by data.gov.sg.
LifestyleHTML · JavaScriptGitHub @beisongOnlineOwner 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
WorthIt — free Singapore HDB & condo resale price explorer. 370K+ transactions, deal scoring, price trends, and BTO launch comparisons. Built on data.gov.sg and URA open data.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
🏠 WorthIt — Singapore Property Value Detective
Instantly check if a Singapore HDB resale flat or private property is fairly priced based on real transaction data from data.gov.sg and URA.
A free tool for Singapore homeowners and buyers — check HDB resale prices, condo transaction history, price trends, and fair-value estimates for any town, district, or project.Read the full README ↗Instantly check if a Singapore HDB resale flat or private property is fairly priced based on real transaction data from data.gov.sg and URA.
A free tool for Singapore homeowners and buyers — check HDB resale prices, condo transaction history, price trends, and fair-value estimates for any town, district, or project.
Check My Price: search any HDB postal code, enter an asking price, and get a 0–100 Deal Score with a fair-value range from storey-adjusted comparable sales nearby — flat type, size, floor, and remaining lease are inferred automatically from the block's transaction history.
WorthIt uses a split architecture:
public/) served via Cloudflare Pages (or node server/index.js locally)/api/* (public/config.js sets API_BASE = ''): locally Express serves it; in production the Cloudflare Pages Function (functions/[[path]].js) proxies it to Fly.ionpm install
pip install requests pyproj # for data download scripts
npm run download-hdb # HDB transactions (~230K records)
# npm run download-ura # Optional: URA private property data (requires URA_API_ACCESS_KEY)
This downloads HDB resale transaction records from data.gov.sg into server/db/resale.db.
npm start
Open http://localhost:3000 in your browser. Express serves both the frontend and API.
npm install -g flyctl
fly auth login
fly launch # Follow prompts (choose region, set app name)
fly secrets set ONEMAP_TOKEN=your_token_here # optional, for geocoding
fly deploy
The Fly.io free tier (256MB RAM) is too small to run the Python download scripts. Instead, build the database locally and upload it:
# 1. Build database locally
python scripts/download_data.py
python scripts/download_ura_data.py # optional
# 2. Upload to Fly.io volume
fly ssh sftp put server/db/resale.db /data/resale.db
# 3. Restart the machine to pick up the new DB
fly machine restart <machine-id>
curl https://<your-app>.fly.dev/api/status
# Expected: {"status":"ok","total_transactions":370252,"latest_month":"2026-05",...}
fly logs # live log stream
fly logs --no-tail # recent logs only
fly machines list # list all machines and their states
fly machine status <id> # detailed status of a machine
fly ssh issue # one-time: create SSH certificate
fly ssh console # open a shell on the machine
Inside the SSH shell:
ls -la /data/ # check database file exists
ls -la /app/ # check deployed files
curl localhost:8080/api/status # test API from inside the machine
cat /app/server/index.js | head # verify deployed code
fly ssh sftp put local_file.txt /data/remote_file.txt # upload
fly ssh sftp get /data/resale.db ./downloaded.db # download
fly machine restart <machine-id> # restart a specific machine
fly machines restart # restart all machines
| Problem | Cause | Fix |
|---|---|---|
503 Database not ready | No DB file on volume | Run download scripts locally, then fly ssh sftp put |
| OOM kill on SSH | Not enough RAM for Python | Build DB locally and upload via SFTP |
| SSH auth failed | No SSH certificate | Run fly ssh issue then fly ssh establish |
no_database status | DB missing at /data/resale.db | Upload via SFTP |
# Re-download latest data locally
python scripts/download_data.py
# Re-upload to Fly.io
fly ssh sftp put server/db/resale.db /data/resale.db
fly machine restart <machine-id>
npx wrangler pages deploy public --project-name=worthit
First run will prompt browser authentication. This uploads public/ and gives you a live URL (e.g., https://worthit.pages.dev).
public# Re-deploy after changes
npx wrangler pages deploy public --project-name=worthit
The frontend auto-connects to the Fly.io API via config.js.
The frontend is live at worthit.canlah.app. Here's how it was configured:
canlah.app) → Continueworthit.canlah.appcurl -I https://worthit.canlah.app
# Should return HTTP 200 with Cloudflare headers
| Endpoint | Description |
|---|---|
GET /api/status | Database status and record count |
GET /api/towns | List all HDB towns + district labels |
GET /api/flat-types | List all flat types |
GET /api/resolve?q= | Resolve town name or postal code |
GET /api/area-overview?town= | Main HDB market overview endpoint (accepts lat/lng for 500m radius) |
GET /api/valuation?postal=&price= | Deal Score + fair value from storey-adjusted nearby comps |
POST /api/geocode | Batch geocode addresses |
POST /api/feedback | In-app feedback (rate-limited, separate feedback.db) |
GET /api/private/projects?q= | Search private property projects |
GET /api/private/project-overview?project= | Private project details |
GET /api/private/property-types | List private property types |
GET /api/private/district-summary?districts= | District aggregate stats |
GET /api/private/district-overview?district= | Full district overview |
GET /api/nearby-hdb?lat=&lng= | Nearby HDB transactions + private projects (800m) |
GET /api/bto/launches | All BTO launches grouped by exercise |
GET /api/bto/projects?q= | BTO project autocomplete |
GET /api/bto/project-overview?project= | BTO project flats, nearby-resale comparison, and own resales once past MOP |
GET /api/seo/metadata?route= | Bot metadata for edge-function injection |
GET /api/seo/sitemap | Sitemap URLs (consumed by Cloudflare edge function) |
WorthIt/
├── scripts/
│ ├── download_data.py # HDB data download (data.gov.sg)
│ ├── download_ura_data.py # URA private property data
│ ├── bto_launches.json # Hand-curated BTO launch data
│ ├── fetch_bto_blocks.py # BTO project → HDB blocks (OneMap)
│ └── bto_project_blocks.json # Output of fetch_bto_blocks.py
├── server/
│ ├── index.js # Express API server
│ └── db/
│ ├── resale.db # SQLite database (generated)
│ └── feedback.db # In-app feedback (writable, generated)
├── functions/
│ └── [[path]].js # Cloudflare edge: /api proxy, bot SEO injection, sitemap
├── public/
│ ├── index.html # Main SPA
│ ├── config.js # API base URL config (same-origin)
│ ├── css/
│ │ └── styles.css
│ └── js/
│ ├── api.js # API client
│ ├── app.js # Main app logic
│ ├── charts.js # Chart.js configs
│ └── map.js # Leaflet map
├── Dockerfile # Fly.io Docker config
├── fly.toml # Fly.io app config
├── package.json
├── requirements.txt
└── README.md
Prices shown are indicative and based on historical transaction data. They should not be considered as professional valuations. Always consult a licensed valuer or property agent for formal advice.