<?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: Kevin Yi</title>
    <description>The latest articles on DEV Community by Kevin Yi (@kevin7yi).</description>
    <link>https://dev.to/kevin7yi</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%2F4182118%2Fbc131433-bbb2-4863-8682-fb8f7ed0c031.png</url>
      <title>DEV Community: Kevin Yi</title>
      <link>https://dev.to/kevin7yi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevin7yi"/>
    <language>en</language>
    <item>
      <title>Scheduling social posts across time zones without breaking on DST</title>
      <dc:creator>Kevin Yi</dc:creator>
      <pubDate>Sun, 01 Nov 2026 03:42:05 +0000</pubDate>
      <link>https://dev.to/kevin7yi/scheduling-social-posts-across-time-zones-without-breaking-on-dst-1dm1</link>
      <guid>https://dev.to/kevin7yi/scheduling-social-posts-across-time-zones-without-breaking-on-dst-1dm1</guid>
      <description>&lt;p&gt;If you have ever built a "post this at 9am" feature, you have probably shipped at least one daylight saving time bug. Here are the rules I now follow for any scheduling code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Store the user's intent, not just a timestamp
&lt;/h2&gt;

&lt;p&gt;A user who says "every Monday at 9:00 in Berlin" means local wall-clock time. Store:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"local_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"09:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tz"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Europe/Berlin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rrule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FREQ=WEEKLY;BYDAY=MO"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then compute the next UTC instant when you enqueue the job. If you only store a UTC timestamp, the post drifts by an hour after the clocks change.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Handle the gaps and overlaps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring forward&lt;/strong&gt;: 02:30 does not exist on that day. Move to the next valid minute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fall back&lt;/strong&gt;: 01:30 happens twice. Pick the first occurrence and document it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. One queue, many networks
&lt;/h2&gt;

&lt;p&gt;When one post goes to several networks, keep a single scheduled job and fan out at publish time. Each network gets its own retry state, so a failed TikTok upload does not block the LinkedIn post.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Test with fixed clocks
&lt;/h2&gt;

&lt;p&gt;Inject the clock into your scheduler and write tests for the two DST transition days of every time zone you support.&lt;/p&gt;




&lt;p&gt;I ran into all of these while working on a &lt;a href="https://socialmediascheduler.cc/?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=guest_post"&gt;social media scheduler&lt;/a&gt; that publishes to 11 networks. The same logic powers the per-network pages such as the &lt;a href="https://socialmediascheduler.cc/tiktok-scheduler?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=guest_post"&gt;tiktok scheduler&lt;/a&gt; and &lt;a href="https://socialmediascheduler.cc/youtube?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=guest_post"&gt;youtube shorts scheduler&lt;/a&gt;. If you are building something similar, start with rule #1 and most of the other bugs never appear.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>FLUX.3 Klein vs Seedream 5.5: Picking an Image Model for Text-Heavy Designs</title>
      <dc:creator>Kevin Yi</dc:creator>
      <pubDate>Sun, 01 Nov 2026 03:22:03 +0000</pubDate>
      <link>https://dev.to/kevin7yi/flux3-klein-vs-seedream-55-picking-an-image-model-for-text-heavy-designs-11i6</link>
      <guid>https://dev.to/kevin7yi/flux3-klein-vs-seedream-55-picking-an-image-model-for-text-heavy-designs-11i6</guid>
      <description>&lt;p&gt;If your generated images need readable text (posters, packaging, slides, UI mockups), the model choice matters more than the prompt. Here is how two 2026 releases compare.&lt;/p&gt;

&lt;h2&gt;
  
  
  FLUX.3 Klein (Black Forest Labs, Oct 15 2026)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open weights, 5.6B parameters, with a Qwen3-VL text encoder&lt;/li&gt;
&lt;li&gt;One model for text-to-image, single-image editing, up to 10 reference images and bounding-box placement, up to 4K&lt;/li&gt;
&lt;li&gt;Runs on an 8 GB GPU with the INT8 build; works in ComfyUI and Diffusers&lt;/li&gt;
&lt;li&gt;About a cent per 1K image via API; free commercial use under $5M yearly revenue&lt;/li&gt;
&lt;li&gt;Its prompt-expansion step rewrites short prompts into detailed ones, which is why bold headlines and labels come out clean from a one-line brief&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where it slips: small lines of text and non-Latin scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seedream 5.5 (ByteDance)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Closed model, built for text-heavy layouts&lt;/li&gt;
&lt;li&gt;More accurate small text in Chinese, English, Japanese, Thai and other languages&lt;/li&gt;
&lt;li&gt;Edits stay stable over many rounds&lt;/li&gt;
&lt;li&gt;Native transparent (RGBA) output with up to 100 layers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rule of thumb
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Self-hosting, budget drafts, bold headline posters: &lt;strong&gt;FLUX.3 Klein&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Bilingual posters, infographics with captions, long edit sessions: &lt;strong&gt;Seedream 5.5&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found this &lt;a href="https://seedream55.org/flux-3-klein-vs-seedream?utm_source=dev.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=guest_post"&gt;FLUX.3 Klein vs Seedream 5.5 text rendering comparison&lt;/a&gt; useful: it has side-by-side samples (stamps, sale posters, gig posters, infographics, tea tins) and per-image prices at 1K, 2K and 4K.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Keeping the same character across every scene in AI video generation</title>
      <dc:creator>Kevin Yi</dc:creator>
      <pubDate>Tue, 13 Oct 2026 11:56:04 +0000</pubDate>
      <link>https://dev.to/kevin7yi/keeping-the-same-character-across-every-scene-in-ai-video-generation-1npj</link>
      <guid>https://dev.to/kevin7yi/keeping-the-same-character-across-every-scene-in-ai-video-generation-1npj</guid>
      <description>&lt;p&gt;Most text-to-video models are great at a single shot and bad at a sequence. Ask for one cartoon scene, then ask for the next one, and the main character quietly changes face, hair colour and body proportions between cuts. Across 30–60 seconds that reads as a bug rather than a style choice, which is exactly the problem I ran into while building &lt;a href="https://toonbeeai.net/" rel="noopener noreferrer"&gt;ToonBee AI Cartoon Animation Generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is what the problem actually is, and the approach that ended up working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the character drifts
&lt;/h2&gt;

&lt;p&gt;Three things stack up against you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Each generation is stateless.&lt;/strong&gt; The model has no memory of the shot you generated thirty seconds ago. Every scene is a fresh sample from the same distribution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text is a lossy way to describe a face.&lt;/strong&gt; "A young girl with brown hair and a red hoodie" is compatible with thousands of faces. Sampling twice gives you two of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style and identity are entangled.&lt;/strong&gt; If you push the prompt to fix the style, you often move the character with it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The practical result: the first shot looks great, and the fifth shot looks like a different person.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approach that worked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Anchor on an image, not a description.&lt;/strong&gt; A reference image is a much denser constraint than a sentence. Once the character is pinned to a picture, you stop asking the model to re-invent a face on every scene.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate identity from staging.&lt;/strong&gt; The character reference and the scene description are two different inputs. Scene 1 might be "on a rooftop at sunset", scene 2 "in a kitchen", but the character block stays byte-identical between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lock the look before you animate.&lt;/strong&gt; Pick the cartoon style once for the whole video. Mixing styles mid-video is the fastest way to break the illusion, even if the face holds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate audio after the visuals.&lt;/strong&gt; Narration and music are laid under a finished timeline. Trying to time visuals to pre-generated audio makes scene boundaries fight the audio, and you end up regenerating both.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this buys you
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One upload, then the same face, outfit and proportions in every scene.&lt;/li&gt;
&lt;li&gt;Either a full script or a one-line idea — the scenes get written for you when you only have the idea.&lt;/li&gt;
&lt;li&gt;16:9 for YouTube, native 9:16 for Shorts, Reels and TikTok.&lt;/li&gt;
&lt;li&gt;Commercial use on every plan, and a credit cost shown per scene before it renders.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it still breaks
&lt;/h2&gt;

&lt;p&gt;Worth being honest about the limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistency holds &lt;em&gt;within&lt;/em&gt; one video. Jumping between unrelated projects means a fresh reference.&lt;/li&gt;
&lt;li&gt;Big changes of age or costume mid-video still need a new reference, not just a new prompt.&lt;/li&gt;
&lt;li&gt;Long videos cost more, because every scene is a generation. The per-scene credit preview exists so this is not a surprise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;If you want to see the difference a reference image makes, &lt;a href="https://toonbeeai.net/" rel="noopener noreferrer"&gt;ToonBee AI&lt;/a&gt; gives you 100 free credits on signup, no watermark on downloads, and a 9:16 export for short-form. The free tier is enough to render a short story end to end.&lt;/p&gt;

&lt;p&gt;Curious how others are solving character consistency — reference-image conditioning, or something else?&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
  </channel>
</rss>
