<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Memduh PANPALLI</title>
    <description>The latest articles on DEV Community by Memduh PANPALLI (@panpalli).</description>
    <link>https://dev.to/panpalli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3953891%2F795dffee-5eb0-499a-a0c4-71bcce9e35a7.jpeg</url>
      <title>DEV Community: Memduh PANPALLI</title>
      <link>https://dev.to/panpalli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/panpalli"/>
    <language>en</language>
    <item>
      <title>A quiet Product Hunt launch showed me what my AI workspace was missing</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Thu, 18 Jun 2026 11:14:21 +0000</pubDate>
      <link>https://dev.to/panpalli/a-quiet-product-hunt-launch-showed-me-what-my-ai-workspace-was-missing-m99</link>
      <guid>https://dev.to/panpalli/a-quiet-product-hunt-launch-showed-me-what-my-ai-workspace-was-missing-m99</guid>
      <description>&lt;p&gt;I launched Fluxerv on Product Hunt recently.&lt;br&gt;
The launch was quieter than I hoped, but it showed me something useful: the product needed to get new users to the core value much faster.&lt;br&gt;
Fluxerv is a workspace where notes can become working interactive tools.&lt;br&gt;
Instead of switching from notes to an AI chat, then copying code somewhere else, you can type &lt;code&gt;/ai&lt;/code&gt; inside a note and generate a working component directly in the document.&lt;br&gt;
I recorded a short demo where I generated a World Cup-style group standings calculator inside a note.&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/QFtllFK4ueI"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
The component is interactive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;score inputs update the standings live&lt;/li&gt;
&lt;li&gt;points and goal difference are calculated automatically&lt;/li&gt;
&lt;li&gt;the UI can be refined without leaving the page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson for me was not simply “the launch was quiet. It was that first-run activation matters. If someone lands on the product and does not quickly reach the moment where a note turns into a working tool, the value is easy to miss.&lt;br&gt;
So I’m now focusing on making that first working-component moment happen much earlier.&lt;/p&gt;

&lt;p&gt;I’d love feedback from other builders and developers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the value clear from the demo?&lt;/li&gt;
&lt;li&gt;Would you use this workflow for planning, teaching, product work, or dev notes?&lt;/li&gt;
&lt;li&gt;What part feels confusing or unnecessary? &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Try Fluxerv:&lt;br&gt;
&lt;a href="https://www.fluxerv.com" rel="noopener noreferrer"&gt;https://www.fluxerv.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>saas</category>
      <category>productivity</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I built a note app where /ai creates working tools inside the note</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Wed, 17 Jun 2026 06:14:25 +0000</pubDate>
      <link>https://dev.to/panpalli/i-built-a-note-app-where-ai-creates-working-tools-inside-the-note-2h8p</link>
      <guid>https://dev.to/panpalli/i-built-a-note-app-where-ai-creates-working-tools-inside-the-note-2h8p</guid>
      <description>&lt;p&gt;I recorded a quick demo of Fluxerv to make the core idea easier to understand.                                                                                                 &lt;/p&gt;

&lt;p&gt;Fluxerv is a workspace where your notes can become working interactive tools.                                                                                                  &lt;/p&gt;

&lt;p&gt;In the demo, I typed &lt;code&gt;/ai&lt;/code&gt; inside a note and generated a World Cup-style group standings calculator. The component runs directly inside the document:                          &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;score inputs update the standings live
&lt;/li&gt;
&lt;li&gt;points and goal difference are calculated automatically
&lt;/li&gt;
&lt;li&gt;the UI can be refined without leaving the page
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the main idea: not a screenshot, not a static note, not a code block.                                                                                                  &lt;/p&gt;

&lt;p&gt;Notes that run code.                                                                                                                                                           &lt;/p&gt;

&lt;p&gt;Demo video: &lt;br&gt;
    &lt;iframe src="https://www.youtube.com/embed/-6vXxCvj2Wc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Fluxerv:&lt;br&gt;&lt;br&gt;
  &lt;a href="https://www.fluxerv.com" rel="noopener noreferrer"&gt;https://www.fluxerv.com&lt;/a&gt;                                                                                                                                                        &lt;/p&gt;

&lt;p&gt;Product Hunt launch:&lt;br&gt;
  &lt;a href="https://www.producthunt.com/products/fluxerv?launch=fluxerv" rel="noopener noreferrer"&gt;https://www.producthunt.com/products/fluxerv?launch=fluxerv&lt;/a&gt; &lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>saas</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Fluxerv is live on Product Hunt today</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Tue, 16 Jun 2026 07:27:25 +0000</pubDate>
      <link>https://dev.to/panpalli/fluxerv-is-live-on-product-hunt-today-52g4</link>
      <guid>https://dev.to/panpalli/fluxerv-is-live-on-product-hunt-today-52g4</guid>
      <description>&lt;h2&gt;
  
  
  Fluxerv is live on Product Hunt today
&lt;/h2&gt;

&lt;p&gt;After 3 months of building solo, today is launch day.&lt;/p&gt;

&lt;p&gt;Fluxerv is a workspace where you type &lt;code&gt;/ai&lt;/code&gt; in any note, describe a tool you need, and a working interactive component appears directly inside your document. Calculator, data formatter, color picker, anything you describe. The thinking and the output stay on the same page.&lt;/p&gt;

&lt;p&gt;Free to start. 20% off Pro with code &lt;code&gt;PH20OFF&lt;/code&gt; this week.&lt;/p&gt;

&lt;p&gt;If you want to support the launch:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.producthunt.com/products/fluxerv" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;producthunt.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>saas</category>
      <category>buildinpublic</category>
      <category>ai</category>
    </item>
    <item>
      <title>What building alone actually feels like</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Thu, 11 Jun 2026 04:38:56 +0000</pubDate>
      <link>https://dev.to/panpalli/what-building-alone-actually-feels-like-4b6m</link>
      <guid>https://dev.to/panpalli/what-building-alone-actually-feels-like-4b6m</guid>
      <description>&lt;p&gt;Nobody tells you what building alone actually feels like.&lt;/p&gt;

&lt;p&gt;The blog posts make it sound clean. You have an idea, you build it, you launch. Maybe you hit some technical walls, you push through, and eventually things work out.&lt;/p&gt;

&lt;p&gt;What they skip is the part where you sit in front of your laptop for three hours and produce nothing useful. Or the part where you ship something and hear silence. Or the part where you start questioning whether the whole thing even makes sense.&lt;/p&gt;

&lt;p&gt;That part is most of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The decision load nobody warns you about
&lt;/h2&gt;

&lt;p&gt;When you build alone, every single decision is yours.&lt;/p&gt;

&lt;p&gt;Not just the technical ones. What to name things, how to price them, what to say on the landing page, which bug is worth fixing today and which one can wait. You make dozens of these calls every day, and most of them have no clearly right answer.&lt;/p&gt;

&lt;p&gt;After a while, the weight of that accumulates. Decision fatigue is real, and it hits harder when there is no one to share it with.&lt;/p&gt;

&lt;p&gt;The upside is that you move fast. No alignment meetings, no waiting for someone to sign off. But the downside is you also carry the full weight of every wrong call.&lt;/p&gt;




&lt;h2&gt;
  
  
  The silence after you ship
&lt;/h2&gt;

&lt;p&gt;There is a specific feeling that comes after you push something live.&lt;/p&gt;

&lt;p&gt;For a few minutes you feel good. Then you open analytics. Then you wait. Then you check again. Then you start wondering if anyone will ever find this, or if the landing page copy is wrong, or if you should have built something else entirely.&lt;/p&gt;

&lt;p&gt;Shipping is supposed to feel like progress, and sometimes it does. But more often it just opens a new kind of uncertainty.&lt;/p&gt;

&lt;p&gt;The work does not stop at launch. In some ways it gets harder.&lt;/p&gt;




&lt;h2&gt;
  
  
  Progress that does not look like progress
&lt;/h2&gt;

&lt;p&gt;Software development has this property where nothing visible happens for a long time, and then suddenly it does.&lt;/p&gt;

&lt;p&gt;You spend days tracking down a bug. You rewrite a component that looked fine but was causing subtle issues. You read documentation for a feature you thought would take an hour. None of that shows up anywhere. There is no visible output.&lt;/p&gt;

&lt;p&gt;Then one day the thing works, and the next thing works, and the day after that you have something you could not have imagined a week ago.&lt;/p&gt;

&lt;p&gt;The hard part is the in-between. You have to keep going during the periods when it does not look like you are going anywhere, because usually you are.&lt;/p&gt;




&lt;h2&gt;
  
  
  The comparison trap
&lt;/h2&gt;

&lt;p&gt;You will spend time looking at what other people are building.&lt;/p&gt;

&lt;p&gt;Some of it is useful. You learn things, you get ideas, you see what is working. But a lot of it just makes you feel behind. Someone else launched faster, has more users, raised money, built a team.&lt;/p&gt;

&lt;p&gt;The problem with comparing is that you are seeing their output and comparing it to your process. You do not see the false starts, the pivots, the things they tried that did not work. You see the finished thing and measure yourself against it.&lt;/p&gt;

&lt;p&gt;The only comparison that actually helps is you versus yourself last week.&lt;/p&gt;




&lt;h2&gt;
  
  
  What keeps you going
&lt;/h2&gt;

&lt;p&gt;Everyone has a different answer to this. Some people are driven by the users they already have. Some people just need to know the thing is possible. Some people genuinely enjoy the building itself and treat everything else as secondary.&lt;/p&gt;

&lt;p&gt;What probably does not work, at least not long term, is pure willpower. Grinding through something you do not care about is exhausting in a way that compounds quickly.&lt;/p&gt;

&lt;p&gt;The founders who stick with it tend to have some version of the same thing: they actually care about the problem. Not the startup, not the metrics. The problem. And they are curious enough about the solution that building it keeps being interesting even when it is hard.&lt;/p&gt;




&lt;h2&gt;
  
  
  The part that does not go away
&lt;/h2&gt;

&lt;p&gt;Here is the honest version: building alone does not get easier. You just get better at knowing what to expect.&lt;/p&gt;

&lt;p&gt;The silence after a launch still happens. The stretches where nothing seems to move still happen. The moment where you wonder if it is worth continuing still happens.&lt;/p&gt;

&lt;p&gt;What changes is that you stop treating those things as signals that something is wrong. They are just part of it.&lt;/p&gt;

&lt;p&gt;The people who keep going are not the ones who found a way to skip that part. They are the ones who decided to keep going anyway.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something? fluxerv.com&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>solofounder</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>What I learned building a SaaS alone for 3 months</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Wed, 10 Jun 2026 15:37:06 +0000</pubDate>
      <link>https://dev.to/panpalli/what-i-learned-building-a-saas-alone-for-3-months-538p</link>
      <guid>https://dev.to/panpalli/what-i-learned-building-a-saas-alone-for-3-months-538p</guid>
      <description>&lt;p&gt;I didn't have a co-founder. No team, no office, no standup meetings. Just me, a laptop, and a feature I couldn't get to work.&lt;/p&gt;

&lt;p&gt;The feature was the whole point of the app.&lt;/p&gt;

&lt;p&gt;You type &lt;code&gt;/ai&lt;/code&gt; in a document, describe a tool you need, and a working interactive component appears inline. Not a code block. A real, running UI inside your note.&lt;/p&gt;

&lt;p&gt;Simple to describe. Hard to build.&lt;/p&gt;




&lt;h2&gt;
  
  
  The part that broke me first
&lt;/h2&gt;

&lt;p&gt;Getting AI-generated code to render safely inside a rich text editor is not straightforward.&lt;/p&gt;

&lt;p&gt;The component had to be sandboxed so it couldn't touch the parent app, but still functional enough to do useful things. I got that wrong more times than I want to admit.&lt;/p&gt;

&lt;p&gt;The iframe configuration, the CSP headers, the streaming approach, each one had an edge case I didn't see coming. I'd fix one thing and break another.&lt;/p&gt;

&lt;p&gt;Some days the only visible progress was a slightly better understanding of why it didn't work.&lt;/p&gt;




&lt;h2&gt;
  
  
  The moment I knew it could ship
&lt;/h2&gt;

&lt;p&gt;Then one day I typed a prompt, and the component started generating.&lt;/p&gt;

&lt;p&gt;Not a broken render. Not a half-working preview. A real, interactive tool appearing inside the document as the AI wrote it.&lt;/p&gt;

&lt;p&gt;That was the moment I thought: this is different.&lt;/p&gt;

&lt;p&gt;Not because the code was perfect, but because the experience felt like something that didn't exist before. The tool and the thinking behind it, living in the same place.&lt;/p&gt;

&lt;p&gt;After that, finishing felt possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  What three months alone actually teaches you
&lt;/h2&gt;

&lt;p&gt;You make every decision.&lt;/p&gt;

&lt;p&gt;Tech stack, pricing, copy, color of a button. Nobody to delegate to, nobody to blame.&lt;/p&gt;

&lt;p&gt;It's clarifying in a way I didn't expect. You stop overthinking and just ship, because the alternative is sitting still.&lt;/p&gt;

&lt;p&gt;You also learn what the product actually is by building it. My initial idea shifted significantly. The core stayed, but the details changed constantly as I ran into real problems.&lt;/p&gt;

&lt;p&gt;The hardest part wasn't the code. It was the stretches where nothing seemed to be moving.&lt;/p&gt;

&lt;p&gt;Progress in software is invisible until suddenly it isn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where it is now
&lt;/h2&gt;

&lt;p&gt;Fluxerv is live. Free to start, no waitlist.&lt;/p&gt;

&lt;p&gt;I'm launching it on Product Hunt on June 16, 2026, with 20% off Pro using code &lt;code&gt;PH20OFF&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're building something alone and feel stuck, keep going. The gap between "this doesn't work" and "this is exactly what I imagined" is usually smaller than it looks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.fluxerv.com" rel="noopener noreferrer"&gt;https://www.fluxerv.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Why I built a notes app instead of yet another AI chatbot</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Wed, 10 Jun 2026 11:00:54 +0000</pubDate>
      <link>https://dev.to/panpalli/why-i-built-a-notes-app-instead-of-yet-another-ai-chatbot-1kd0</link>
      <guid>https://dev.to/panpalli/why-i-built-a-notes-app-instead-of-yet-another-ai-chatbot-1kd0</guid>
      <description>&lt;p&gt;Every developer I know takes notes. Meeting notes, architecture ideas, quick references — it all ends up somewhere, usually scattered across five different tools.&lt;/p&gt;

&lt;p&gt;I was doing the same thing. And at some point I noticed a pattern: I'd write a note describing a UI idea, then open a separate tool to actually build it, then come back to the note. The thinking and the output lived in completely different places.&lt;/p&gt;

&lt;p&gt;Most AI tools I looked at had the same shape: you ask, it answers. You copy the output, paste it somewhere, run it. The AI is a consultant you have to carry the work for.&lt;/p&gt;

&lt;p&gt;That gap bothered me more than I expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap nobody talks about
&lt;/h2&gt;

&lt;p&gt;So I started thinking about what it would look like if the output just stayed where the thinking happened. Not a code block you copy. Not a link you follow. A working, interactive component, right inside the note.&lt;/p&gt;

&lt;p&gt;That's the core idea behind Fluxerv. You type &lt;code&gt;/ai&lt;/code&gt;, describe what you want, and a live component appears in your document. A calculator, a color picker, a data formatter — whatever you need. You can refine it with natural language, share the whole document with anyone, and the component works for them too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why notes matter as much as the AI
&lt;/h2&gt;

&lt;p&gt;The notes part matters as much as the AI part. A developer writing about a feature doesn't just want to describe it. They want to show it. When the component and the context live on the same page, the document becomes something you actually use — not just something you wrote once and forgot.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it started
&lt;/h2&gt;

&lt;p&gt;I didn't set out to build another notes app or an AI coding assistant. I just kept running into the same friction, and eventually the only way to get rid of it was to build the thing myself.&lt;/p&gt;

&lt;p&gt;If you've felt the same gap — &lt;a href="https://fluxerv.com" rel="noopener noreferrer"&gt;fluxerv.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I built /ai inside a notes app -here's how I render generated UI components safely</title>
      <dc:creator>Memduh PANPALLI</dc:creator>
      <pubDate>Wed, 27 May 2026 08:35:55 +0000</pubDate>
      <link>https://dev.to/panpalli/i-built-ai-inside-a-notes-app-heres-how-i-render-generated-ui-components-safely-emc</link>
      <guid>https://dev.to/panpalli/i-built-ai-inside-a-notes-app-heres-how-i-render-generated-ui-components-safely-emc</guid>
      <description>&lt;p&gt;I take a lot of notes while I'm working. Meeting notes, quick ideas, system design sketches — all of it ends up somewhere.&lt;/p&gt;

&lt;p&gt;The frustrating part was never &lt;em&gt;writing&lt;/em&gt; the notes. It was what happened after. I'd describe a UI idea in a note — a color picker, a calculator, a data formatter — and then I'd have to open a separate editor, build the thing, test it, and come back. The note and the tool lived in completely different places.&lt;/p&gt;

&lt;p&gt;At some point I thought: what if the tool just lived &lt;em&gt;inside&lt;/em&gt; the note?&lt;/p&gt;

&lt;p&gt;That's what I've been building for the past few weeks. You type &lt;code&gt;/ai&lt;/code&gt; in the editor, describe what you want, and a working interactive component appears inside your document. Not a screenshot. Not a code block. A real, running UI.&lt;/p&gt;

&lt;p&gt;Here's what that looks like mid-generation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr16t058g1ga32rvt5m7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr16t058g1ga32rvt5m7a.png" alt="Fluxerv AI generating a component in real time" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the streaming moment — the AI is writing the component live, and it appears inside the note as it generates.&lt;/p&gt;

&lt;p&gt;Let me walk through how I built this.&lt;/p&gt;




&lt;h2&gt;
  
  
  The editor foundation
&lt;/h2&gt;

&lt;p&gt;I'm using &lt;a href="https://tiptap.dev/" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt; — a headless, extensible rich text editor for React. Tiptap is built on ProseMirror, which means you can define custom nodes: blocks that behave however you want inside the document.&lt;/p&gt;

&lt;p&gt;I created a custom &lt;code&gt;AiNode&lt;/code&gt; — a Tiptap node that holds generated HTML/CSS/JS as a string in its attributes. When the node renders, it shows a live iframe. The node persists to Supabase as part of the document's JSON content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AiNodeExtension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aiComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;addAttributes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple enough. The hard part was &lt;em&gt;getting the code into the node&lt;/em&gt; while streaming.&lt;/p&gt;




&lt;h2&gt;
  
  
  The streaming problem
&lt;/h2&gt;

&lt;p&gt;The AI backend uses Gemini 2.5 Flash via Server-Sent Events. The model streams the HTML, CSS, and JS as one big string — character by character.&lt;/p&gt;

&lt;p&gt;The problem: I needed to show this output &lt;em&gt;live&lt;/em&gt; inside the Tiptap node while it was still being generated. Users shouldn't stare at a spinner for 10 seconds.&lt;/p&gt;

&lt;p&gt;My first approach was to update the rendered output on every streamed chunk. It worked, but it caused too many re-renders and made the editor feel heavy.&lt;/p&gt;

&lt;p&gt;The better approach was to decouple streaming from rendering: accumulate the generated code in a ref while the stream is active, then render the final result once inside a sandboxed iframe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;accumulated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// On each chunk:&lt;/span&gt;
&lt;span class="nx"&gt;accumulated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;

&lt;span class="c1"&gt;// On stream close:&lt;/span&gt;
&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aiComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;accumulated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The node re-renders once, the iframe appears, the component runs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The sandbox setup
&lt;/h2&gt;

&lt;p&gt;The iframe uses this sandbox configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
  &lt;span class="na"&gt;sandbox=&lt;/span&gt;&lt;span class="s"&gt;"allow-scripts"&lt;/span&gt;
  &lt;span class="na"&gt;srcdoc=&lt;/span&gt;&lt;span class="s"&gt;{generateSrcdoc(code)}&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's missing: &lt;code&gt;allow-same-origin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is intentional and critical. Without &lt;code&gt;allow-same-origin&lt;/code&gt;, the iframe cannot access &lt;code&gt;localStorage&lt;/code&gt;, cookies, or the parent document's DOM. The AI-generated code runs in complete isolation. It can't read your tokens, it can't exfiltrate data, it can't touch anything outside its own sandbox.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;allow-scripts&lt;/code&gt; alone is enough for interactive components to work — timers, event listeners, DOM manipulation inside the frame, all fine.&lt;/p&gt;

&lt;p&gt;I also inject Tailwind CSS via CDN inside the iframe's &lt;code&gt;srcdoc&lt;/code&gt; so generated components can use utility classes without any build step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateSrcdoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;script src="https://cdn.tailwindcss.com"&amp;gt;&amp;lt;/script&amp;gt;
        &amp;lt;style&amp;gt;
          body { background: #09090b; margin: 0; padding: 16px; }
        &amp;lt;/style&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The refine system
&lt;/h2&gt;

&lt;p&gt;Once a component is generated, users can update it with natural language. There's a "Refine" button in the component toolbar. You type something like "make the background darker" or "add a reset button" — and the component updates.&lt;/p&gt;

&lt;p&gt;The naive approach would be to regenerate the entire component from scratch. That works but it's slow and wasteful.&lt;/p&gt;

&lt;p&gt;Instead, I built a &lt;code&gt;/api/edit&lt;/code&gt; endpoint that receives two things: the current component code and the edit instruction. The system prompt wraps them together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are editing an existing UI component.

Current code:
[CURRENT_CODE]

Edit instruction:
[INSTRUCTION]

Return only the updated full component code. No explanations.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model returns the full updated component — but it only needs to reason about the delta. In practice this is faster and produces more coherent edits than full regeneration.&lt;/p&gt;

&lt;p&gt;The response streams the same way as generation, and the node updates when it's done.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I got wrong
&lt;/h2&gt;

&lt;p&gt;A few things that cost me time:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stale closures in Tiptap.&lt;/strong&gt; If you reference &lt;code&gt;editor&lt;/code&gt; inside a &lt;code&gt;useEffect&lt;/code&gt; without including it in the dependency array, you'll be working with a stale editor instance. Commands will silently fail. This one took a while to track down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limiting before you think you need it.&lt;/strong&gt; I added Upstash Redis rate limiting to both endpoints early on. Good call — during testing I hit Gemini's limits faster than expected. Shared rate limiter utility across both endpoints so I wasn't duplicating logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The middleware gap.&lt;/strong&gt; My Next.js middleware was redirecting unauthenticated users to login — including the &lt;code&gt;/share/&lt;/code&gt; route for public documents and the &lt;code&gt;/api/&lt;/code&gt; routes. Had to explicitly whitelist these paths. Simple fix, annoying to debug.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where it is now
&lt;/h2&gt;

&lt;p&gt;The app is called &lt;strong&gt;Fluxerv&lt;/strong&gt;. It's live at &lt;a href="https://fluxerv.com" rel="noopener noreferrer"&gt;fluxerv.com&lt;/a&gt; — free to start, no waitlist.&lt;/p&gt;

&lt;p&gt;Here's a 2-minute demo of it generating a pomodoro timer from a single prompt:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2059512944497660320-402" src="https://platform.twitter.com/embed/Tweet.html?id=2059512944497660320"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2059512944497660320-402');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2059512944497660320&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The stack: Next.js (App Router), Tiptap v3, Supabase, Gemini 2.5 Flash, Tailwind CSS, Upstash Redis.&lt;/p&gt;

&lt;p&gt;Launching on Product Hunt on June 16 — 20% off Pro with code &lt;strong&gt;PH20OFF&lt;/strong&gt; during launch week.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've built something similar or ran into the same iframe/streaming problem, I'd love to hear how you solved it. Drop a comment. And if you want to try it yourself — &lt;a href="https://fluxerv.com" rel="noopener noreferrer"&gt;fluxerv.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
