Building the Same App Using Various Web Frameworks


Hey friends,

Recently, I've been wondering if I should migrate from my current web app stack (FastAPI, HTML, CSS, and some JavaScript) towards a modern web framework. I was particularly interested in FastHTML, Next.js, and Svelte. To learn more about these frameworks, I built the same web app using each of them. Here's what I learned, plus some thoughts on how coding assistances can and will influence developer habits and choices.

I appreciate you receiving this, but if you want to stop, simply unsubscribe.

• • •

👉 Read in browser for best experience (web version has extras & images) 👈

Recently, I’ve been wondering if I should migrate from my current web app stack (FastAPI, HTML, CSS, and a sprinkle of JavaScript) to a modern web framework. I was particularly interested in FastHTML, Next.js, and Svelte.

  • FastHTML: Many folks have started building with it since Jeremy Howard launched it a month ago. Its goal is to enable modern web applications in pure Python.
  • Next.js: I’ve come across several apps built with it such as cal.com and roomGPT. It has a large ecosystem and is popular for building production-grade web apps.
  • SvelteKit: This lightweight framework has been popular with devs (Stack Overflow, TSH, State of JS) and my friend Swyx (Why I Enjoy Svelte) over the past few years.

To learn more about these frameworks, I built the same web app using each of them. The app, which I’m calling “Look at Your Data”, allows users to:

  • Upload a CSV file to initialize an SQLite database table
  • View the table in the web browser
  • Update individual fields in the table
  • Delete individual rows in the table
  • Download the updated table data as a new CSV file

By implementing these CRUD (Create, Read, Update, Delete) operations in each framework, I hope to get a sense of each framework’s unique features and the associated developer experience. To keep things simple, I’ll use SQLite as the database. As a baseline, I’ll start by building the app with what I’m familiar with—FastAPI.

I ran polls on the three frameworks on Twitter and LinkedIn

FastAPI + Jinja + HTML + CSS + JavaScript

Building the app with FastAPI is fairly straightforward (code). The key components are:

  • main.py: Routes for uploading/downloading data, updating fields, deleting rows
  • index.html: The HTML document that defines the scripts, table, and buttons.
  • style.css: Visual styling such as column widths, word wrap, scrolling.
  • script.js: Client-side functionality for uploading the CSV, loading data for display, updating/deleting rows, and downloading the updated data as CSV.

Here’s what the web app looks like. While it’s not much to look at aesthetically, it meets our requirements above. I’ve deliberately kept visual styling to a minimum (for the current and later apps) to keep the focus on the frameworks and functionality instead of design.

FastHTML

To learn FastHTML, I started by consulting the docs and building a simple ToDo app via this walkthrough. For help with unfamiliar components, I relied on Cursor by providing links to relevant docs such as ft components, htmx, pico.css as context. With FastHTML, I could implement the entire app within a single main.py and a small style.css (code).

Here’s how the app looks.

After my first iteration above, Hamel graciously offered to pair-program with me to build the app from scratch. He also invited Jeremy Howard—the creator of FastHTML himself—to join us. They taught me several tricks, such as providing Cursor with LLM-friendly documentation for FastHTML (llms-ctx.txt) and FastLite (html.md). They also shared a great resource on building simpler apps with htmx and Hyperview. Jeremy even took the time to demonstrate how to build the app in just 50 lines of code!

And here’s how Jeremy’s app looks:

Next.JS

To learn Next.js, I did the React Foundations and Next.js tutorials. The latter teaches the basics of Next.js through bite-sized, hands-on lessons that build up to a dashboard app. With 16 chapters in the Next.js tutorial, learning and coding along can take some time. Nonetheless, I recommend persisting till at least Chapter 12 on transforming data (in the Next.js tutorial), and enjoyed the gentle learning curve and practical projects.

Here’s how I created the Next.js app template:

npx create-next-app@latest

Building the same app in Next.js requires considerably more code than the Python versions (code). Nonetheless, I found its organization intuitive:

  • api: Routes for the data table (GET, PUT, DELETE) and file upload/download
  • pages.tsx and layout.tsx: Page-specific and common user interface components
  • components: Reusable React components like table and upload/download buttons
  • lib: Utility functions; in this case, there was a single function for SQLite

And here’s how the web app looks. The built-in Tailwind CSS integration makes the app look a bit more polished compared to the barebones FastAPI and FastHTML apps.

SvelteKit

To learn Svelte, I went through part of their tutorial that comes with an online interpreter. The tutorial has four parts: (i) Basic Svelte, (ii) Advanced Svelte, (iii) Basic SvelteKit, and (iv) Advanced SvelteKit. I completed the sections on basic Svelte and basic SvelteKit and jumped into building the app (code).

To create the SvelteKit app template, I ran the following:

npm create svelte@latest my-app

Like Next.js, the template for SvelteKit has several directories and moving parts:

  • components: Reusable Svelte components such as data table and upload buttons
  • api.ts and db.ts: Functions for the API to fetch, update, and delete data (api.ts) as well as query and run updates on the SQLite database (db.ts)
  • routes: Routes for table (GET), rows (PUT, DELETE), and upload/download
  • +page.svelte: Main page of the application
  • app.html: Entry point and main HTML file

Here’s how the app looks. One slight deviation: I played with combining the “choose file” and “upload” functionality into a single button, thus removing the “Upload CSV” button.

FastAPI + Svelte

I also took a stab at building an app with FastAPI as the backend and Svelte for the frontend (code). All functionality and APIs resided in main.py while frontend UI and API interactions were handled by +page.svelte and api.ts respectively. To run the app, I had to start both the FastAPI server and the Svelte development server.

And here’s what the web app looks like. (I reverted the upload functionality to match the original FastAPI app that had a separate “Upload CSV” button.)

The main challenge here was coordinating communication between both servers during development. In a production setting, the Svelte app would be compiled and served statically with API requests sent to the FastAPI backend.

• • •

Aside: How will coding assistants influence builders?

This exercise got me thinking about how coding assistants—powered by LLMs trained on internet data—could influence the choices we make as builders. For example, would LLM-based coding assistants be as effective with niche or newer frameworks such as Svelte and FastHTML? While the tweet below may be an exaggeration, it raises a valid concern.

It brings me no pleasure to say this, but Svelte is dead because LLM base models are better at writing React. — Jess Martin

Given React and Next’s wider use and longer history, it’s likely most LLMs are trained on more React and Next code than Svelte code. Ditto for FastHTML. This could lead to coding assistants being more effective when working with and suggesting code for established frameworks such as FastAPI, React, and Next.js.

As an anecdote, I had an easier time using Cursor + Claude to build the app in FastAPI and Next.js, and a harder time with FastHTML and SvelteKit. Since FastHTML is barely a couple weeks old (at the time of writing), its code and docs likely hasn’t made its way into the training data of most LLMs yet, explaining their limited proficiency with FastHTML.

To address this issue, Jeremy Howard (creator of FastHTML) has made the effort to provide llms.txt and llms-ctx.txt that have been optimized for in-context learning. Similarly, Rich Harris (who works on Svelte at Vercel) plans to publish more LLM-friendly documentation for Svelte. Victor Dibia has also written about how coding assistants may affect developer habits and choices, and how we need to write docs for both humans and machines.

Time will tell how effective these efforts are in addressing the cold-start problem for newer or more niche frameworks in coding assistants.

• • •

This was a fun exercise to gain familiarity with FastHTML, Next.js, and SvelteKit. All the code can be found here. (I’m a beginner in frontend so please forgive any bad practices!) Personally, I’m looking forward to building more with TypeScript, which I haven’t used extensively since building ApplyingML.com years ago.

What resources have you found useful in learning how to build with Next.js or Svelte? Please comment below or dm me!

Eugene Yan

I build ML, RecSys, and LLM systems that serve customers at scale, and write about what I learn along the way. Join 7,500+ subscribers!

Read more from Eugene Yan

Hey friends, I've been thinking and experimenting a lot with how to apply, evaluate, and operate LLM-evaluators and have gone down the rabbit hole on papers and results. Here's a writeup on what I've learned, as well as my intuition on it. It's a very long piece (49 min read) and so I'm only sending you the intro section. It'll be easier to read the full thing on my site. I appreciate you receiving this, but if you want to stop, simply unsubscribe. 👉 Read in browser for best experience (web...

Hey friends, Just got back from the AI Engineer World's Fair and it was a blast! I had the opportunity to give the closing keynote, as well as host GitHub CEO Thomas Dohmke for a fireside chat. Along the same lines, I've been thinking about how to interview for ML/AI engineers and scientists, and got together with Jason to write about the technical and non-technical skills to look for, how to phone screen, run interview loops, and debrief, and some tips for interviewers and hiring managers....

Hey friends, Recently a couple of friends and I got together to write about some challenges and hard-won lessons from a year of building with LLMs. One thing led to another and this is now published on O'Reilly in three sections: Tactics: Prompting, RAG, workflows, caching, when to finetune, evals, guardrails Ops: Looking at data, working with models, product and risk, building a team Strategy: "No GPUs before PMF", "the system not the model", how to iterate, cost We have a dedicated site...