A few months ago I started a side project that I thought would take a weekend. Famous last words, right? My partner and I had just moved into a slightly bigger apartment, and we were having the classic argument every couple has after moving: where does the couch go, does the desk fit under the window, and is there enough room for a reading chair next to the bookshelf? I figured, I'm a developer, surely I can build a small floor plan tool faster than I can measure everything with a tape measure and a notebook.
Reader, I could not.
What follows is a write-up of the rabbit holes I fell into, the bugs that ate my weekends, and the moment I gave up on doing everything myself and started leaning on an AI tool to do the heavy lifting. If you're thinking about building any kind of 2D editor — floor plans, diagrams, seat maps, whatever — I hope this saves you some pain.
The naive first attempt
My first version was a React app with a plain <canvas> element. I had a state object that looked roughly like this:
const [walls, setWalls] = useState([]);
const [furniture, setFurniture] = useState([]);
const [selectedId, setSelectedId] = useState(null);
Draw a wall by clicking two points. Drag furniture around. Easy. I had something working in about four hours. I was feeling great.
Then I tried to add a second room. Then I tried to make walls snap to each other. Then I tried to compute the area of each room. Everything fell apart.
The core problem is that a floor plan is not a list of walls. It is a planar subdivision — a graph of vertices and edges that partition the plane into faces. Once you understand that, you realize you have just signed up for computational geometry homework, and not the fun kind.
The bugs that broke me
There were three bugs that ate most of my time.
The first was wall snapping. When the user drags the end of a wall close to another wall, it should snap. Sounds easy. But what if the other wall is at an angle? What if there are three candidates within the snap radius? What if snapping creates a degenerate polygon with zero area? I wrote a snapping function, then a function to fix the bugs the snapping function created, then a function to fix the bugs that function created. By the end I had a 400-line file called geometryHelpers.js and I was scared of it.
The second was room detection. Given a soup of wall segments, find the closed rooms. The textbook algorithm involves building a doubly-connected edge list (DCEL), sorting half-edges by angle around each vertex, and walking the faces. I read three papers and watched a CMU lecture on YouTube at 1.5x speed. I got it kind of working. It crashed on any input with a T-intersection.
The third was performance. Once I had a few dozen walls and was redrawing on every mouse move, the canvas started chugging on my older laptop. I needed dirty-region rendering, requestAnimationFrame batching, and a quadtree for hit-testing. None of this was the project I signed up for. I just wanted to know if the couch fit.
Giving up gracefully
At some point — I think it was around 2 a.m. on a Tuesday, debugging why a wall was showing up as both inside and outside the same room — I closed my laptop and admitted I was nerd-sniping myself. The actual goal was to plan my apartment, not to ship a CAD engine.
The next morning I went looking for tools I could either integrate with or just use directly. I tried a few. Most were either overkill (full architectural suites that cost more than my rent) or underkill (drag-and-drop room templates with no real measurements). Then I found floor plan AI, which sat in a sweet spot I didn't expect. You can describe a room in plain language or upload a rough sketch, and it generates a clean 2D plan with measurements. For my use case — figuring out furniture layout in an existing apartment — it was honestly more useful than the half-built tool I had been wrestling with.
I ended up using it to generate the base plan of the apartment, then exporting that and overlaying my furniture experiments on top in my own little React app. Suddenly the hard part was done for me and I could focus on the part I actually cared about: where the couch goes.
What I kept from the side project
Even though I shelved the ambition of building a full editor, the side project wasn't wasted. A few things I'm keeping for future work.
First, immutable state with structural sharing is non-negotiable for any editor. I switched from raw arrays to Immer partway through and undo/redo became almost free. If you are building anything with history, do this on day one, not day fourteen.
Second, separate the data model from the rendering. My early code mixed pixel coordinates and world coordinates everywhere, and it was a nightmare when I added pan and zoom. The fix was a strict rule: the data model only knows about meters. The renderer is the only thing that ever touches pixels. Once I drew that line, half my bugs evaporated.
Third, geometry libraries are your friend. I eventually pulled in polygon-clipping and flatten-js and stopped trying to implement Sutherland-Hodgman from a Wikipedia article at midnight. There are people who have spent their careers on robust 2D geometry. Use their work.
Fourth, and this is the meta-lesson, know when to stop building and start integrating. I am a developer, so my reflex is always to build. But the value I was trying to create for myself was a furniture layout, not a codebase. Outsourcing the hard, generic part of the problem to a tool that already solved it let me get back to the specific, fun part much faster.
Would I build it again?
Yes, but differently. If I came back to this project, I would start with an existing geometry kernel, accept that I'm building a thin UI layer on top of someone else's math, and integrate an AI plan generator for the cold-start problem of getting an initial layout. The hand-rolled DCEL adventure was educational, but it was not productive.
If you are about to start a similar project, my honest advice is to ask yourself what you actually want. If you want to learn computational geometry, great, do it the hard way, and have fun. If you want a floor plan, use a tool that already makes floor plans and spend your weekend on something else. I picked the wrong one for a while, and now I have a slightly tidier living room and a much healthier respect for the people who build editors for a living.
Thanks for reading. If anyone has good resources on robust planar subdivision algorithms that won't make me cry, drop them in the comments — I'm still curious, just no longer on a deadline.
Top comments (0)