Building RenterPro: A Trailer Booking App's First Few Weeks
The Brief
I saw a client that was using a paper system to keep track of their business operations for their trailer rental business. I asked if I could build them an app to get them to be more paperless and go digital. Over some time and some iterations of prototypes, I knew I had the UI/UX more or less down but now it was time to think of how to store said booking details per trailer.
Starting Point: A Prototype
At the prototyping stage I had the client use the web app side by side with their paper system.
There were a couple of issues, some edge cases and flows that we addressed and tackled. The clients had a sense of ownership and contribution to the final product, which I thoroughly enjoyed. I wanted to ensure that the solution I'm providing was set to tackle all their pain points, streamline daily business operations, and prevent admin errors.
Over time the web app matured and features have slowly been iterated overtime. Continuous improvement cycles to get the final polished product.
Tech Stack Decisions
React + TypeScript + Vite — fast local dev, no framework overhead
FullCalendar (resource-timeline) — the fleet view, from the first commit
Tailwind CSS + Radix UI — quick, accessible UI without a design system to maintain
The very first commit was deliberately thin: a Vite-scaffolded React app, Tailwind for styling, Radix for the dialog/button primitives, and everything — trailers, customers, bookings — held in React state, seeded from a mock data file. No backend, no database. The goal was to get the calendar feeling right before worrying about persistence.
The Calendar Problem
The hardest part wasn't picking a library — it was tuning how bookings actually behaved once the client started using it day to day:
- Switching between day, week, and month views without losing context on where you were
- Dragging a booking to extend or move it, with a distinct hover state so you always knew whether you were moving the whole booking or just its edge
- Copy-and-paste for repeat bookings, since the same regular customers kept renting the same trailer
- Getting the default booking time right so a new booking didn't need three form edits before it made sense
Because every trailer is its own row on the timeline, an overlapping booking is visually obvious the moment you drag it — the calendar does the "conflict detection" just by being a resource-timeline, without needing a separate rules engine underneath it.
Key Commits Along the Way
Here's the rough shape of the first five weeks, from first commit to the point the app got a real database:
Week 1 — Foundation
first commit— Vite + React + TypeScript scaffold, mock data, resource-timeline calendarUpdated calendar stylesAdding a booking and adding Select from react-select to add a filter in the customer list
Week 1–2 — Booking & Invoicing
add invoice, added trailer filteringand set calendar to be by the houradded color on hover for both drag options on the booking
Week 2 — Interaction Polish
big changes adjusted drag and extend, and added copy paste functionalityadd bash file to start application— a one-click launcher for a non-technical userupdated trailer list updated invoice functionality and layout
Week 2–3 — Real-World Fixes
Updated days view and booking behaviorupdates remove deposits, updated default booking timesUpdates to weekly button placement and two weeks from a day before today
Week 5 — Persistence
Added SQLite DB, updated edit customer flows, updated DB schemas for booking to include payment type
That last one mattered most: everything before it lived only in the browser's memory and reset on refresh. Adding SQLite (via better-sqlite3) behind a small Express API turned it from a prototype into something a business could actually rely on day to day.
What I'd Do Differently
Held off on the database a little too long. Building the whole booking and invoicing flow against in-memory mock data was great for iterating on the calendar UX fast, but it meant a real migration once SQLite landed — re-shaping how the app fetched and saved data instead of just extending it.
Underestimated how much the little interaction details would matter. Drag-hover colour states, default booking times, exact button placement for switching weeks — none of these were in the original scope, but they're what made the person actually running the desk trust the tool instead of falling back to the spreadsheet.
The resource-timeline view was the right call from day one. It would have been easy to start with a generic calendar grid and bolt on a "which trailer" dropdown. Going straight for one row per trailer meant the fleet-at-a-glance view — the whole point of the project — was there from the first commit, not retrofitted later.
Result, So Far
By week five, the client had gone from a paper and phone calls to a system that:
- Shows the entire fleet on one screen, trailer by trailer
- Makes booking a matter of dragging a block onto a timeline
- Makes overlapping bookings visually obvious before they become a real problem
- Persists everything to a real database instead of living in browser memory
- Handles cash-ups, invoicing, and digital signage — all paperless
This was still very much a web app at this point — running locally in the browser during development. What came after this — packaging it as a proper installable desktop app with React and Electron — is its own story, for another post.
More posts incoming — including how RenterPro went from a local web app to a packaged desktop install. If you have a project you'd like to discuss, get in touch.