FEWO Search

Full-stack · booking platform

Express

SQLite

SQL

SSE

Role

Design, front-end & backend

Year

2026

A holiday-rental portal built on a raw Airbnb export: 1,476 listings, 504,795 calendar nights and 103,295 reviews, behind a search, a booking flow and a live availability feed. Express and SQLite on the server, hand-written JS in the browser. No front-end framework, no build step.

1476

listings

504k

calendar nights

23

API endpoints

0

front-end frameworks

FEWO running in a browser on a laptop: search bar with the filter panel open, over the listing carousel

01 — Finding something

Search first, form second

The dataset is 1,476 listings in one city. Small enough to browse, large enough that browsing gets you nowhere. So the landing page is a search bar and a carousel, and everything that narrows the set sits one popover away, visible when you want it and gone when you do not.

Landing

The More Filter popover: price range slider, minimum rating stars, rooms and type selects, and an apply button showing 1476

Filters

The full listing grid: 1476 Unterkünfte, a sort select, and six cards per row

All listings

02 — Booking it

The calendar is the product

Half a million calendar rows exist to answer one question honestly: can I have these nights, and what do they cost. Every rule below is checked in the browser so the answer is instant, and again on the server so the answer is true.

Listing calendar for August 2026 with a selected range, struck-out unavailable days, a price summary and a minimum-nights warning

Availability

Booking form: listing recap, check-in and check-out, total price, name and address fields, guest count and a requests box

Booking form

Booking confirmation: green check, dates, nights and total price, with buttons to bookings or back to the listing

Confirmation

03 — Deciding the interface

What each screen is instead of

A booking interface has an obvious version, and the dataset kept breaking it. Each decision below beat a more conventional one, and it lost for a reason that came out of the data rather than out of taste. They are written as pairs, what it is and what it is instead of, because a decision with no discarded alternative was never really a decision.

04 — Under it

What the server actually does

Ten dependencies, eight routers, one SQLite file. The interesting part was never a single endpoint. It was deciding which problems deserved a library and which deserved twenty lines.

05 — Admin & leftovers

The plain half, and what is still wrong

The admin side is deliberately plain: an import form, a dashboard, a dark-mode switch. Four things are still wrong and I would rather write them down than crop them out of a screenshot. The login token lives in localStorage, which CSP and escaping make less bad but do not fix. bookings.json is rewritten after every change and never read back, so it is a mirror pretending to be a store. The 2-minute reservations sit in memory and vanish on restart. And the pay button charges nobody.

Profile page: dark-mode toggle and an admin block with CSV import forms for listings, calendar and reviews

Profile — admin section

Every decision on this project, written down, including the ones that turned out wrong. Twenty pages. Nobody has to read it.

Menu