To Dark Mode
Featured Images
Photo by Kier in Sight Archives on Unsplash

How I Rebuilt a 2018 Project in 2025

Modern Web Development, Vibe Coding, Serverless, and Practical Data Automation

Zhenghao Wu

Status: Finished Confidence: 8

Post Details

Table of Contents

Prelude: The Django and jQuery Days

In 2018, I was self-studying the Django web framework for a college course. To apply what I was learning, I decided to build a project to solve a real problem: our school’s course information system.

All official course information was contained within a single, large PDF file. And course details contains in more individual handbooks PDF files. Finding a specific course was a time-consuming process that required extensive scrolling and text searches. I believed I could create a more efficient and user-friendly solution.

This led to the creation of uicCourse.

uicCourse Homepage

It was built entirely in Python with a Django backend and server-side rendered templates. Over its development, I added numerous features:

uicCourse Course Page

The project was eventually passed to a UICHCC and remains operational today, serving as a snapshot of the web development practices of that time.

However, as the project’s complexity increased, its limitations became apparent. The monolithic codebase developed a complex network of dependencies. My initial database schema, with its heavy use of foreign keys, made data updates difficult. As the frontend requirements grew, the constraints of using Django templates and raw jQuery became a significant bottleneck for creating interactive elements.

I eventually archived the project, but the goal of creating a better version remained.

Motivation: Overcoming the React Hurdle with AI Assistance

For years, learning React (or Vue) was on my to-do list, but it presented a significant hurdle. My attempts to start a project often led to a frustrating cycle of build tool errors, complex configurations, and package incompatibilities.

Then came LLM coding agents. Tools like GitHub Copilot and Cline became my 24/7 coding partner.

Large Language Models (LLMs) provided a new way to work through technical challenges. They functioned as both a mentor for explaining concepts and a pair programmer for generating code. I could describe a goal, provide an error message, or ask for an explanation, and the agent would provide step-by-step guidance.

With this support, I successfully overcame the initial learning curve and built a small image management application with Next.js. This experience gave me the confidence to undertake a modern rebuild of uicCourse.

The side project was a small image management application built with Next. I was planning to keep maintaining it, but I found out there is a better solution call immich, so I archived it.

The new project, coursedb, would be built with a clean architecture, an improved user experience, and a clear plan for long-term maintenance.

The Tech Stack: From Monolith to Modern Full-Stack

The T3 Stack, created and promoted by content creator Theo, heavily influenced my choice of technologies. It provides a great starting point for full-stack applications.

The technological evolution from the 2018 project to the 2025 rebuild is clear:

Component uicCourse (2018) coursedb (2025) Rationale for the Change
UI Framework Bootstrap CSS + jQuery Tailwind CSS + shadcn/ui From pre-styled components to a utility-first, highly customizable design system. But also providing a modern and unified component library.
Backend Django (Python) Next.js + tRPC (TypeScript) A unified full-stack TypeScript environment for seamless front-to-back development.
Database SQLite PostgreSQL (on Supabase) From a simple file-based DB to a robust, scalable, and fully managed SQL database.
ORM Django ORM Drizzle ORM Moving to a lightweight, TypeScript-native ORM for end-to-end type safety.
Authentication Django Auth NextAuth.js From a solid but rigid system to a flexible, provider-agnostic auth solution.
Hosting Docker on a VPS Vercel + Supabase From manual server management to a fully managed, serverless infrastructure with CI/CD.

coursedb Homepage

This new stack represents a philosophical shift toward prioritizing developer experience (DX), type safety, and high efficiency. This allows me to focus on implementing business logic rather than configuring boilerplate.

Design and Architecture: Lessons Learned

Database Schema: In uicCourse, I over-relied on foreign keys, believing maximal relational integrity was always best. I learned this can lead to a rigid schema that makes data imports and future migrations difficult. For coursedb, the schema is more modular and loosely coupled, defined with Drizzle ORM for flexibility and programmatic seeding. I also uses features from PostgreSQL, such as JSONB columns, to store complex data structures like reviews.

API Layer: I replaced Django’s monolithic views with tRPC, which has been a significant improvement. Defining API procedures in TypeScript provides end-to-end type safety between the backend and frontend without requiring code generation or OpenAPI specifications. This makes the entire application feel like a single, cohesive codebase.

Frontend: The new UI is built with the Next.js App Router, Server Components, and Tailwind CSS. The design uses a persistent sidebar for navigation, a shift from Bootstrap’s simpler layout. Using shadcn/ui accelerated the creation of consistent and accessible components. The developer experience is a stark contrast to the previous workflow, offering features like hot-reloading and a typed, component-based architecture.

Authentication: While Django’s built-in auth is effective for basic needs, integrating social logins or modern protocols like OIDC can be complex. NextAuth.js is designed for this flexibility, integrating smoothly with Next.js and simplifying the addition of multiple authentication providers. Now I am using Discord and GitHub for authentication, which is more convenient for users. (Discord is good for development, because it allow to set multiple redirect endpoints)

Database & ORM: SQLite was sufficient for the original project but has performance limitations with concurrent writes. (Though it never gone popular and I never had a problem with it) PostgreSQL provides a high-performance and scalable solution. When developing locally, T3 stack provides a quick way to set up a PostgreSQL database with Docker. For production, I use Supabase for its managed PostgreSQL service, which simplifies deployment and scaling. While the Django ORM is an excellent tool, it choice Drizzle ORM for its lightweight, TypeScript-native design.

coursedb Course Page

Practical Data Automation: From Manual Entry to an Automated Pipeline

The data entry process for the 2018 project was entirely manual. I copied course data from the official PDF and entered it into the system’s forms. This was a highly repetitive task that took weeks to complete, driven by a concern that batch processing might introduce errors.

My new data pipeline is now fully automated and takes minutes:

  1. Extraction: The source PDF is converted to raw text using the pdftotext utility.
  2. Structuring: A combination of regular expressions, custom rules is used to parse the unstructured text into organized data blocks (e.g., course codes, descriptions, prerequisites).
  3. Refinement with AI: This is the most innovative step. The structured data is processed by an LLM using carefully crafted prompts to perform several tasks:

I now approach data handling with the same principles as coding: it is composable, iterative, and automated. This not only saves a significant amount of time but also results in richer, more accurate data.

If the data have errors, I can quickly identify and fix them in the source text, re-run the pipeline, and regenerate the entire dataset. Gradually improves the quality is quite a fun process.

From Repetitive CRUD to Collaborative “Vibe Coding”

A large portion of the development time for the original system was spent on repetitive CRUD (Create, Read, Update, Delete) tasks. Each new feature required manually building UI forms, writing view logic, and handling validation.

My current workflow is more collaborative. And AI scientist Andrej Karpathy call it “vibe coding”—a process of working with an AI agent. I describe the desired functionality at a high level, and the agent scaffolds the initial implementation. For example:

“Generate a tRPC procedure for coursedb to manage course reviews. It should support pagination, include user information, validate ratings are between 1 and 5, and only allow the review’s author to delete it.”

This produces a functional, type-safe starting point in seconds. My role shifts from writing boilerplate code to refining the logic, verifying correctness, and guiding the overall architecture. This method does not replace the developer but rather augments their capabilities.

Which AI Coding Agent to Use?

I have used several tools. Each has its strengths and weaknesses:

For other popular tools like Cursor, Roo Code. I tried them but not experienced them extensively. You can check out their documentation and see if they fit your workflow.

Final Lessons and Takeaways

Revisiting this project provided technical insights and a measure of my growth as a developer.

  1. Design for Change. My 2018 schema was too rigid. The 2025 version prioritizes flexibility, acknowledging that requirements will evolve.
  2. Type Safety is a Key Advantage. The combination of TypeScript, Drizzle, and tRPC prevents entire classes of runtime errors, enabling faster and more confident development.
  3. Automate Processes. My initial hesitation toward automation was a major bottleneck. A well-designed script with proper validation is far more efficient and reliable than manual repetition.
  4. The Developer’s Role Remains Central. AI coding agents are powerful tools that handle execution, but the developer is responsible for setting goals, making architectural decisions, and ensuring quality.

The journey from uicCourse to coursedb reflects the broader evolution in web development toward more automated, component-based, and efficient workflows. It has been a valuable experience, and I look forward to seeing how these tools and methodologies continue to advance.

Article Card

For "How I Rebuilt a 2018 Project in 2025"


Related Posts