17:00:09CCU, IN
Back to projects

From Frustration to Flow: Reimagining the Presentation Engine

Last updated: November 29, 2025

How a stressful academic deadline sparked an idea worth building—and everything I learned along the way.


The Spark

It started with a bottleneck.

My friends and I were building a project, but we hit a wall: Presentation Day. I got stuck with making the slide deck. Despite loving the code we'd written, pixel-pushing slides felt jarring. It was stressful, repetitive, and ate up hours we didn't have.

Then after a few days of searching for a better option which could help next time, I discovered Chronicle. I was completely blown away by how effortless it felt. It wasn't just about "making slides", it was about getting something polished instantly, with zero friction. I got hooked.

I spent hours inspecting their network requests, try to dissect the architecture, trying to understand the magic. The way they handled state management, the streaming responses, the real-time updates, it seemed cool. Chronicle stopped being just a tool and became something I was genuinely curious about. Maybe because I'd never seen anything like it, or maybe it was just how well-crafted the product felt.

That deep dive changed everything. I didn't just want to use a tool like this, I wanted to build one. Not just to solve my own frustration, but to satisfy my curiosity and challenge myself as an engineer.


The Vision

4 Clicks to Done.

I wanted to strip away the noise and build a platform where users could:

  1. Create custom decks from a simple prompt
  2. Refine the AI's outline before generating slides
  3. Edit with a smooth, intuitive interface
  4. Share in one click

The Stack

Next.jsReactTiptapPrismaZustandRedisShadcnTailwindPostgreSQLBetter-Auth


Engineering Highlights

1. The "Ghost" State (Redis Optimization)

One of the most interesting challenges was distinguishing between a fresh AI generation and a presentation that already exists. I could have just hammered the database, one request isn't too much, but that felt monotonous, like something I'd been doing forever. I was a bit stubborn about finding a different approach. I nudged my brain and came up with a few solutions: some wildly ineffective, some that still hit the database. But one felt interesting and taught me something new.

The Solution: I implemented an ephemeral state layer using Redis.

  • When a user hits /create/generate and generates an outline, I assign it a unique ID
  • This ID is stored in Redis with a 5-minute TTL (Time To Live)
  • I use GETDEL to retrieve the data—an atomic operation that fetches the prompt and immediately deletes it from the cache
  • Result: Zero stale data, reduced database load, and a snappy user experience

2. Pixel-Perfect Consistency (The Scaling Engine)

Here's a problem that bugged me for days: slides needed to look identical on every screen. Sounds simple, right? But presentations are weird they're not really "responsive" content. A slide deck on your laptop should look exactly the same when projected on a massive screen, down to the pixel. .

The Fix: I ditched responsive breakpoints entirely for the slide canvas. Instead, I built a scaling system using CSS transform.

  • The slide container has a fixed logical size, let's say 1920×1080
  • The app calculates the viewport dimensions and applies a scale factor to fit
  • The content itself never reflows,it just scales up or down proportionally
  • What you see in the editor is exactly what gets presented, every single time

3. Optimistic UI Updates (Buffer State Pattern)

Slide edits needed to feel instant. Any lag during editing would kill the user experience, and disrupt the flow while tailoring according to needs.

The Approach: I implemented a buffer state layer between the editor and the main presentation store.

  • Widget updates are captured in a local buffer during active editing
  • On blur (when you click away), the buffer commits to the main Zustand store
  • An auto-save mechanism periodically syncs the store to the database
  • Result: Buttery-smooth editing with zero lag, while maintaining data integrity and automatic persistence

What I Learned

1. Constraint is a feature, not a limitation.

Early on, I thought I needed infinite widget options. I quickly learned that after a certain point, everything starts to look the same. The real value lies in a curated set of flexible, high-quality components that users can reuse, not an endless list of rigid templates.

2. Planning matters, even when it's rough.

Having even a loose blueprint helped me spot potential issues early and build with intention. My "project management system" was just pen, paper, and a tasks.md file, sometimes simple tools are the best tools. Building something I actually was curious and looked forward to kept me motivated and helped me see problems from a user's perspective, not just an engineer's.


What's Next

BYOK Support – "Bring Your Own Key" for users who want to use their own LLM API quotas

Advanced Layouts – Expanding the widget library with interactive data visualizations

Custom Themes – Allowing users to import their own backgrounds and create themes that fit their brand

Performance Optimization – Continuing to refine load times and smooth out any remaining UI jank


This project taught me that the best solutions often come from scratching your own itch. What started as frustration with a school deadline turned into a deep dive on state management, caching strategies, and building products people actually enjoy using.