You know that feeling when you’re sitting with your laptop open, staring at code that looks like hieroglyphics, wondering, “What am I even doing here?” That was me for the past eight months.
I’ve spent years telling myself and others, “I’m not a developer,” while simultaneously writing just enough code to survive.
But something changed recently. I stopped worrying about whether I was a “real developer” and embraced “vibe coding” – building by feel, using AI as my coding partner, and learning just enough to make something useful. The result? After eight months, a fully functional app that’s transformed how I run my LEGO reselling business.
This isn’t about cutting corners. It’s about finding a new path into coding that doesn’t require a computer science degree or years of studying frameworks. It’s about building something real, solving actual problems, and learning along the way.
Here’s how AI helped me go from PowerShell scripts to a full React/Express app without ever formally “learning to code”.
What is “Vibe Coding”?
Vibe coding is a term coined by Andrej Karpathy, a founding member of OpenAI, in February 2025. It describes a new approach to software development in which you let AI do most of the actual coding while you guide it with natural language instructions rather than manually writing code yourself.
The core philosophy is about “fully giving in to the vibes” and almost “forgetting that the code even exists”- focusing on what you want to create rather than how to code it. When you encounter errors, you paste them to the AI without comment, and it usually fixes the issues.
As Karpathy described it, “I just see stuff, say stuff, run stuff, and copy-paste stuff, and it mostly works.” It’s particularly suited for low-stakes projects and prototypes where development speed matters more than perfect understanding of every line of code.
For non-developers vibe coding opens up app creation by letting you focus on creative aspects rather than getting stuck in technical details.
Is it “real” coding? The purists would say no. But here’s what matters: I have a working app that solves real problems in my business, built mostly through conversations with AI. That feels pretty real to me.
And I’m not alone – there’s a whole movement of “vibe coders” emerging. People building software without traditional coding backgrounds, leveraging AI to bridge the gap between what they can imagine and what they can create. It’s democratizing software development in a way that low-code platforms promised but never fully delivered.
The beauty of vibe coding isn’t that it replaces learning – it’s that it lets you build first and learn as you go, in context, solving real problems rather than working through abstract tutorials.

Meet BrickBuddy
My hobby business is selling used LEGO on Bricklink. I enjoy it; low stress and satisfying work that pays a few bills every month. But when you’re dealing with millions of little pieces processing all of that is an absolute nightmare.
So I decided to build an app. First, it was a PowerShell module (yea, a “real” app in PowerShell?). It worked..sorta..but this scenario needed a web application thus BrickBuddy was born.
BrickBuddy is a web app with a ReactJS frontend and an Express application hosting an API on the backend. You can see the landing page I threw together on brickbuddy.io.

My goal was to build an application for myself to run my used LEGO business and maybe at some point sell subscriptions to it.
Because Claude can describe the app much better than I can here’s his take:
Overview
BrickBuddy is a full-stack application designed for managing LEGO brick inventory, with features for tracking, organizing, and managing batches of brick items. The application follows a modern client-server architecture with a clear separation of concerns.
Tech Stack
Frontend (UI)
- Core Framework: React 18 with React Router 6
- State Management: Custom context-based state management with AppStateProvider
- UI Components:
- Tailwind CSS for styling
- Headless UI and Radix UI for accessible components
- React Icons and Hero Icons for iconography
- TanStack React Table for data tables
- React Toastify for notifications
- Chart.js/Recharts for data visualization
- HTTP Client: Axios
- Form Handling: React Select
- Testing: Jest, Testing Library, Playwright
Backend (API)
- Core Framework: Express.js
- Database: Microsoft SQL Server (via Sequelize ORM)
- Authentication: JWT (jsonwebtoken)
- Validation: Joi, Express Validator
- Security: Helmet, bcrypt for password hashing
- Error Handling: Custom error types (ServiceError, ControllerError)
- Logging: Custom Logger implementation
DevOps/Infrastructure
- Build Tools: Craco (Create React App Configuration Override)
- Testing: Jest, Playwright
- CI/CD: GitHub Actions
- Containerization: Scripts for development/production environments
- Environment Management: dotenv, env-cmd
Architecture
Frontend Architecture
The UI follows a well-structured layered architecture:
- Page Container Layer:
- Top-level page components (e.g., UserInventory, Catalog, Batches)
- Manages routing and page-level presentation
- Component Layer:
- Presentational components focused on rendering UI elements
- Follows a clear naming convention (e.g., BatchSelector, LoadingButton)
- Organized by feature rather than type
- Action Handler Layer:
- Custom hooks with naming pattern
use[Component]Handler
- Manages user interactions and UI events
- Maps UI events to business logic operations
- Handles errors and UI state
- Business Logic Layer:
- Custom hooks with naming pattern
use[Feature]Logic
- Contains complex operations independent of UI
- Communicates with backend services
- Handles data transformations
- Service Layer:
- API communication through service hooks
- Abstracts HTTP requests and response handling
- State Management Layer:
- Centralized AppStateProvider using React Context
- State validation through StateActionValidator
- Persistence with localStorage via localSettings utility
- Schema-based state organization with page-specific schemas
Backend Architecture
- Controller Layer:
- Route handlers organized by domain (e.g., BatchController, UserController)
- Validates request data
- Transforms between API contracts and service interfaces
- Handles HTTP response formatting
- Service Layer:
- Contains business logic (e.g., BatchService, UserInventoryItemService)
- Implements domain operations
- Common base service (_BrickBuddyService) for shared functionality
- Error handling with custom ServiceError types
- Model Layer:
- Sequelize models representing database tables
- Defines schema, relationships, and validations
- Organized by entity (e.g., UserModel, BatchModel)
- Middleware Layer:
- Request/response processing
- Authentication and authorization
- Error handling and logging
- Utilities:
- Shared helper functions
- Logging infrastructure
- Error types and formatters
Data Flow
- User interacts with a component
- Action handler processes the interaction
- Business logic is invoked if needed
- API call made through service layer
- API controller receives request
- Controller validates and delegates to service
- Service performs business logic and database operations
- Response flows back through the layers
Key Features
- Batch management for brick inventory
- User inventory tracking
- Integration with external services (Bricklink)
- Set management
- Item location tracking
- User authentication and profile management
- Reporting capabilities
This architecture demonstrates a well-structured application with clear separation of concerns, following modern React and Node.js best practices, with a focus on maintainability, testability, and scalability.
As you can see, this isn’t one of those app that AI influencers spin up in five minutes and all it a clone of Netflix. It’s an entire tech stack including deployment automation with Github Actions, Terraform, a dev and prod environment!
Building real production applications is possible with vibe coding; but requires a completely different thought process and willingness to let go of some details.
All in all, BrickBuddy is currently standing at over 120,000 lines of code!

Granted, 1/4 of that could be trimmed down and simplified but that’s for another blog post.
Starting as a Junior Vibe Coder
I knew how to code. I knew control structures, basic architecture, and some scripting. But I had never touched a frontend framework. I had no idea what a component was, how props worked, or how frontend state was managed.
So I did what any curious builder would do: I opened up Cursor IDE, picked a feature I needed, and typed something like:
“Create a page with a sidebar and a table that shows all my inventory.”
And the AI did it.
At first, this felt like cheating. But then I realized: I still had to test it, understand how it worked, and tweak things. I didn’t understand the syntax, but I started seeing patterns. And eventually, I started caring why something worked, not just that it did.
AI as the Driver, Me as the Passenger
In the beginning, AI was in control. I was just the passenger.
I told it what I wanted, it gave me code, and I pasted it in. I didn’t question the output. I didn’t know how. I didn’t know what a reducer was, or what JSX even meant. I was building blindly, relying on the AI to see for me.
But over time, things started breaking. And when they did, I couldn’t just ask it to fix it. I had to understand the context.
That’s when things started to change.
Breaking Things Taught Me the Framework
The moment something broke and AI couldn’t patch it cleanly, I had to learn. I had to debug. I had to trace where the error started, why a state wasn’t updating, or why a function was getting the wrong value.
That pain was the best teacher.
It taught me the language without tutorials. It taught me architecture without courses. It forced me to get smarter because AI alone wasn’t enough.
Eventually, I stopped telling the AI what to do.
I started asking it questions.
- “What does this warning mean?”
- “Why is this component re-rendering?”
- “Is this a good way to manage state across multiple components?”
And the AI answered. And I learned.
Building Something Real
One of the most important things I learned through this is that building something real is the fastest way to learn.
I wasn’t building a fake app or following a tutorial. I was solving actual problems I had with my LEGO store. I was shipping features that mattered to me. And because of that, I cared about fixing bugs, refactoring code, and learning the right way to do things.
AI made this possible. It let me build before I knew how to build.
It Wasn’t Easy (Despite What Influencers May Say)
This wasn’t a perfect process. I ran into roadblocks, hallucinations, and tons of wasted prompts. I’ve spent over an hour on a single issue, going back and forth with the AI, trying to figure out why something that should work… just didn’t.
Yes, the UI came together fast in the beginning. That part was easy—honestly, that’s maybe 5% of a real application. What took time was everything else:
- Managing state properly
- Handling edge cases
- Fixing bugs that broke other features
- Learning the right way to organize logic across components
I wasn’t just writing code—I was learning architecture, debugging workflows, naming conventions, and React-specific patterns. And I was doing it while trying to build something real that actually worked.
It was frustrating. It was slow. It was confusing.
But it was still faster than if I had tried to learn React from blog posts or YouTube videos. Because I was learning by building, not by studying.
You don’t need to master the language to start. But you do need to be curious. You need to be willing to break things. And most importantly, you need to keep going even when you don’t fully understand what you’re building.
Because eventually, you will.
BrickBuddy exists because I didn’t wait until I was “ready.” I started building, and AI met me where I was.
And 8 months later, I have a real app that works.
That’s the power of coding with AI.
Stay tuned for more posts about my experience in the last year or so building BrickBuddy!