| Live Demo | Source Code |
|---|---|
| Visit site | Github |
When launching a product, the waitlist is often the first real interaction a user has with your brand.
Yet most startups rely on third-party tools that slow down pages, collect user data, or create unnecessary complexity.
I wanted to explore a different approach.
So I built TrackFlow, a lightweight, high-performance waitlist system designed to capture early users while keeping the architecture simple, fast, and fully owned by the product team.
The Real Objective
This project was not just about building a form.
The real goal was to answer an important product question:
How can we capture early users in the fastest and simplest way possible?
For early-stage startups, every signup matters. A slow landing page or unreliable form can directly impact conversion.
Research shows that even a 1-second delay can reduce conversion rates by up to 7%. That means performance is not just a technical concern — it’s a business concern.
TrackFlow was designed to prioritize:
- Fast page load times
- Reliable data capture
- Simple infrastructure
- Full ownership of user data
Project Structure Overview
waitlist├── astro.config.mjs├── components.json├── drizzle│ ├── 0000_first_cassandra_nova.sql│ ├── 0001_lumpy_ezekiel_stane.sql│ └── meta│ ├── 0000_snapshot.json│ ├── 0001_snapshot.json│ └── _journal.json├── drizzle.config.ts├── package.json├── pnpm-lock.yaml├── public│ ├── avatars.webp│ ├── logo.svg│ ├── side-image.webp│ └── site-logo.webp├── README.md├── src│ ├── actions│ │ ├── index.ts│ │ └── subscribe.ts│ ├── assets│ │ ├── astro.svg│ │ └── background.svg│ ├── components│ │ ├── email-form.tsx│ │ ├── hero.tsx│ │ └── ui│ │ ├── button.tsx│ │ ├── form.tsx│ │ ├── input.tsx│ │ ├── label.tsx│ │ └── sonner.tsx│ ├── db│ │ └── schema.ts│ ├── env.d.ts│ ├── layouts│ │ └── Layout.astro│ ├── lib│ │ └── utils.ts│ ├── pages│ │ └── index.astro│ └── styles│ └── global.css├── tsconfig.json└── wrangler.jsoncWhy Not Use a Typical Waitlist Tool?
Many waitlist solutions are built as third-party services. While convenient, they introduce several issues:
- External scripts slow down the landing page
- User data is stored in third-party systems
- Customization and control are limited
For teams that care about performance, privacy, and flexibility, this model can be limiting.
TrackFlow demonstrates a different approach:
build the waitlist directly into your product architecture.
This allows startups to:
- Maintain full control of their user data
- Ensure the fastest possible experience
- Avoid dependency on external platforms
Choosing the Right Stack
To support these goals, I focused on a lightweight and edge-native architecture.
The system combines:
- Astro for fast page rendering
- React for interactive UI components
- Cloudflare D1 for serverless SQL storage
- Drizzle ORM for type-safe database queries
- TypeScript for end-to-end reliability
The result is a full-stack setup that remains simple, scalable, and extremely fast.
Astro vs. Next.js: A Practical Decision
Next.js was actually the first framework I considered.
It is powerful and widely used, especially in the React ecosystem. It also works extremely well when deployed on Vercel.
However, for a performance-focused landing page and waitlist, it introduced unnecessary overhead.
The Challenge with Traditional React Frameworks
Many frameworks ship a large amount of JavaScript to the browser. For highly interactive apps this is fine, but for a waitlist page it can be excessive.
More JavaScript means:
- slower page load
- longer hydration times
- reduced performance on slower devices
Why Astro Was a Better Fit
Astro takes a different approach.
Instead of sending a large JavaScript bundle to the browser, it ships almost no JavaScript by default.
Only the components that need interactivity — such as the signup form — are hydrated.
This results in:
- smaller bundle sizes
- faster page loads
- improved Lighthouse scores
Another advantage is deployment flexibility.
While Next.js works best within the Vercel ecosystem, Astro is cloud-agnostic.
This means the project can be deployed on:
- Cloudflare Pages
- Vercel
- Netlify
- traditional VPS servers
- edge platforms
For teams that want infrastructure flexibility, this is a significant benefit.
Moving the Backend to the Edge
Another important decision was running the application on Cloudflare’s edge network.
Instead of relying on a traditional centralized server, the application runs close to users around the world.
This improves:
- response times
- global performance
- scalability
For early-stage products, this means a better user experience without needing complex infrastructure.
Data Storage with Cloudflare D1
Databases are often the biggest performance bottleneck in web applications.
To reduce latency, the project uses Cloudflare D1, a serverless SQL database designed for edge environments.
Combined with Drizzle ORM, this provides:
- simple SQL queries
- strong type safety
- excellent compatibility with edge runtimes
The result is a data layer that is both fast and easy to maintain.
End-to-End Type Safety
Reliability was another key goal.
Using TypeScript, the database schema and application code share the same types. This means potential issues are caught during development rather than in production.
If a database field changes, the application immediately fails to compile until the code is updated.
This approach significantly reduces runtime errors and improves long-term maintainability.
Performance Results
| Metric | Result |
|---|---|
| Lighthouse Performance Score | 100/100 |
| First Contentful Paint (FCP) | <0.5s |
| JS Bundle Size | ~15kb |
| Database Query Latency | <10ms |
These numbers demonstrate that even a simple waitlist can benefit greatly from a performance-focused architecture.
Lessons Learned
This project reinforced an important idea:
great products often start with simple, well-designed foundations.
Instead of relying on heavy frameworks or complex infrastructure, TrackFlow focuses on:
- simplicity
- performance
- ownership
The result is a waitlist system that is fast, scalable, and ready to grow into a full product.