What is FUNDAMENTALS
FUNDAMENTALS is a series of five web projects built under a single rule: AI does not write my code. Not "AI writes less of it," but none of it. No generated functions, no pasted-in bug fixes, no partial components. Everything that runs was typed by hand.
The rule exists because it's genuinely easy now to assemble a working app without understanding a line of it. That shortcut is fine once you've earned it, but I hadn't, and I wanted proof, mostly for myself, that I could build real things without a crutch underneath me. So AI stays in the room, but only as a mentor: roadmap and stack decisions, architecture discussions, concept explanations, code review after the fact. The moment it would touch implementation, it steps back.
The five projects ramp on purpose, from a vanilla-JS calculator up to a production-grade app with a real backend, auth, and CI. Each one sits a little further past what I was comfortable with when I started it. The point was never purity for its own sake. It's the discipline of sitting with something until I actually understand it, before I let a tool do it for me. Once all five are done, I'll use every tool available. But not yet.
The Calculator
The starting point, and deliberately the smallest possible real thing: a working calculator in plain HTML, CSS, and vanilla JavaScript. No framework, no build step, nothing to hide behind. Just the language itself.
Small as it is, it made a good first rung. The interesting problems weren't visual, they were structural. Learning why user input is best stored as a string rather than a number when you're appending characters one at a time, and how a class can take in DOM references so the logic isn't tangled up with the markup, were the kinds of small foundational lessons that only land when you hit them yourself.
I did put real care into the design, though. Before writing any code I built the whole thing out in Figma, and I wanted the calculator to feel like part of a considered system rather than a default grid of grey buttons: a warm, paper-like palette, restrained type, and a single accent color carrying the operators. Getting that from a static frame into a pixel-faithful layout was its own small exercise in discipline.
My honest reflection here is about process, not code. My first instinct was to build everything from absolute scratch, and I burned hours designing a state model I ended up never using. The lesson that stuck wasn't about calculators, it was about knowing when reinventing the wheel is teaching you something and when it's just costing you time. Studying how existing projects solved the same problem turned out to be the smarter move
The To-Do App
Same foundation, HTML, CSS, and vanilla JS, with localStorage added so tasks survive a refresh. Staying on the vanilla stack for a second project was intentional: one more rep to solidify the fundamentals before stepping up to a framework, this time with the added wrinkle of persisting state.
This one pushed the design and the CSS further than the calculator did. I carried the same visual language forward for consistency, then leaned into the parts a to-do list actually lives on: custom input fields, considered empty and filled states, scrollbar styling, and a real focus on how I structure a stylesheet rather than just making it work. Designing it in Figma first meant I was solving the "what should this feel like when it's empty versus full" question before I ever touched code.
The reflection that matters most came from a security lesson. My first render function dropped user input straight into the page's HTML, which is exactly how you invite a cross-site scripting problem. Refactoring it to build each element individually, safer and as it turned out more modular and easier to reason about, was the real challenge of the project. Like the calculator, my main takeaway was about planning: too many of my refactors existed because I hadn't thought the structure through before I started typing.
The Weather Dashboard
The jump. This is where FUNDAMENTALS stops being about the basics and steps into a modern frontend stack: React, TypeScript, Vite, and a set of tools I'd never touched, TanStack Query for data, Zod for validation, and Leaflet for the map. It's a responsive weather dashboard pulling live data from several sources, with current conditions, forecasts, air quality, and an interactive map, all in a no-scroll layout that reshapes itself across screen sizes.
The design was as much of the work as the code here, and it's the part I dedicated the most hours to. A weather dashboard is fundamentally a layout problem: a lot of distinct information, all wanting to be visible at once, on a screen that shouldn't scroll on desktop. I designed the whole thing in Figma first, wireframing the grid at every breakpoint before committing to it, because the interesting challenge was how the layout should reshape as the screen narrows rather than simply stack. The air quality panel is the clearest example: a full-height rail down the side on desktop that becomes a horizontally-scrolling card lower down on mobile, the same content reorganizing itself rather than being redrawn. Getting those breakpoints to feel deliberate instead of like things awkwardly falling into place was hours of work I'm proud of, and none of it shows up in the README, which is why it belongs here.
Each new tool also changed how I think about a piece of the problem. TanStack Query replaced a whole category of code I'd otherwise have written badly, juggling loading states and dependent requests by hand. Zod answered a question I hadn't thought to ask: what happens to my types when real data shows up at runtime and doesn't match? And Leaflet taught the sharpest lesson, because it doesn't play by React's rules. Bridging an imperative map library into a declarative app was a genuine puzzle, and solving it cleanly felt like the moment the project clicked.
The through-line I'm proudest of on the engineering side is architectural rather than visual. Partway through the build, one of my data providers restructured its API, the kind of change that can ripple through an entire app. Because I'd drawn the boundaries carefully, keeping all the data-shaping in one place and the display components "dumb," the migration was absorbed without a single visual component needing to change. That's the clearest evidence I have that the structure underneath was right.
I'm also honest in the README about what I'd do differently and where the tradeoffs are: building one widget fully end-to-end before repeating the pattern, consolidating helpers as they emerge instead of after, and moving the API key server-side for production. The known limitations are deliberate, documented choices rather than things I missed, which feels like the more valuable skill to be building.
What's next
Two projects remain, and both raise the stakes again.
Movie Searcher moves to Next.js and its App Router, leaning into server-side rendering and streaming. The narrative reason it earns its place: fetching on the server hides the API key, directly fixing the client-side-key limitation I documented in the Weather Dashboard. Each project is meant to answer a problem the last one left open, and this is the clearest example of that.
Expense Tracker is the finale, the "I can ship production software" piece. Next.js with Supabase for a real relational database and auth, Docker for containerization, and GitHub Actions for continuous integration. It's the project that ties the whole series together and proves the point the calculator first set out to make, one full step up the ladder.
Where things stand
Three of five are done, and this is where FUNDAMENTALS pauses. Starting now, mid-July, I'm stepping away for a while to focus on some unrelated projects before I come back for the final two.
Taking stock honestly: the project has done what I hoped, and also shown me exactly where the work still is. React stopped being black magic, TypeScript stopped feeling alien, and I built real architectural judgment I didn't have three projects ago. But I've also learned the difference between understanding something while I'm in it and being able to rebuild it cold, from a blank file, with nothing to lean on. That second skill is the one that actually convinces a recruiter, and it's the one I want to sharpen when I return.
That gap doesn't feel like failure. Projects that feel effortless after one pass usually taught nothing; this one feels earned precisely because parts of it were hard. FUNDAMENTALS was always about proving something to myself before reaching for the easy tools. So far, it's doing exactly that, and the pause is just so the next two projects get the version of me they deserve.