<?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: Seongjin Kang</title>
    <description>The latest articles on DEV Community by Seongjin Kang (@seongjinkang).</description>
    <link>https://dev.to/seongjinkang</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%2F4080765%2F058ffba3-4b54-4897-a201-2455f449404c.png</url>
      <title>DEV Community: Seongjin Kang</title>
      <link>https://dev.to/seongjinkang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seongjinkang"/>
    <language>en</language>
    <item>
      <title>I built a forum where rooms die when people stop talking</title>
      <dc:creator>Seongjin Kang</dc:creator>
      <pubDate>Mon, 17 Aug 2026 02:32:27 +0000</pubDate>
      <link>https://dev.to/seongjinkang/i-built-a-forum-where-rooms-die-when-people-stop-talking-30mc</link>
      <guid>https://dev.to/seongjinkang/i-built-a-forum-where-rooms-die-when-people-stop-talking-30mc</guid>
      <description>&lt;p&gt;I got tired of two things about online communities.&lt;/p&gt;

&lt;p&gt;The first is that they don't die well. A subreddit or a Discord channel that was alive for a week keeps existing for years, and the emptiness is louder than silence — you open it, see the last post is from 2023, and leave. The second is that everything you say is pinned to a permanent profile. Even on "anonymous" apps, you accumulate a history, and the history becomes a reason not to say the true thing.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Noding&lt;/strong&gt;: an anonymous forum where any word becomes a room, and rooms decay when people stop talking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two rules
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A word is a room.&lt;/strong&gt; You type "late night thoughts" or "career anxiety" or "NBA" — if a room exists, you're in it; if not, it exists now. No creation form, no moderator to petition. The search box &lt;em&gt;is&lt;/em&gt; the create button.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rooms decay.&lt;/strong&gt; Every room has an activity score. It gets bumped by visits and posts, and it decays with a 24-hour half-life when nothing happens. &lt;code&gt;active → warning → dormant → gone from the plaza&lt;/code&gt;. If someone opens a dormant room again, it comes back with its history intact — the room only &lt;em&gt;disappears from view&lt;/em&gt;, it doesn't get deleted. So the plaza always shows what's alive right now, and nothing has to be pruned by hand.&lt;/p&gt;

&lt;p&gt;The identity part fell out of these two rules. If there are no profiles, what tells people apart? I ended up using the one thing that's already there: &lt;strong&gt;the path&lt;/strong&gt;. The rooms you pass through, and the order you pass through them, draw a small graph. That graph is rendered as a mark next to your posts. Tap someone's mark and you see the rooms you've &lt;em&gt;both&lt;/em&gt; been in — and nothing else. Their rooms you haven't visited stay blurred. It's the only social feature in the app, and it's asymmetric on purpose: it reveals overlap, never the other person's full history.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's built
&lt;/h2&gt;

&lt;p&gt;Nothing exotic. TypeScript, Express, Socket.IO, MongoDB. React Native (Expo) for the iOS app, and the same codebase exported to web so it works in a browser without installing anything.&lt;/p&gt;

&lt;p&gt;A few pieces that turned out to matter more than I expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The decay scheduler.&lt;/strong&gt; A cron every 15 minutes recomputes &lt;code&gt;nodeActivity&lt;/code&gt; for every room and moves rooms across lifecycle stages. The half-life is a constant; tuning it is the single most important product decision in the app, and it's one number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path as data.&lt;/strong&gt; Every move between rooms is logged as a weighted edge (&lt;code&gt;from → to&lt;/code&gt;, with dwell time). The user's identity mark is literally a rendering of that edge list. It also gives me a "people who walked a similar path" signal for recommendations, without ever asking anyone what they like.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Room similarity.&lt;/strong&gt; Room titles are embedded and stored in Pinecone, so "late night thoughts" and "3am thoughts" know they're neighbors. This is what makes the search-box-as-create-button not fragment into a thousand near-duplicate rooms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moderation before publish.&lt;/strong&gt; Three layers on every post before anyone sees it: a pattern list, fuzzy matching against it, then an LLM pass. Anonymous &lt;em&gt;and&lt;/em&gt; unmoderated is a bad combination; anonymous and moderated is fine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No account before consent.&lt;/strong&gt; A small thing that bit me: the web app used to open a socket (and create a user) as soon as it booted, before the person had agreed to anything. Every crawler that rendered a shared link created a ghost user. Now nothing exists until someone taps "agree." Consent first, account second.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What happened when real people came
&lt;/h2&gt;

&lt;p&gt;It's been running in Korea for a few months. The rooms people make there are mostly what I hoped for: venting about work, reactions to whatever happened today, "anyone else up at 2am."&lt;/p&gt;

&lt;p&gt;Two numbers I keep coming back to. First: people who visit &lt;strong&gt;six or more rooms&lt;/strong&gt; in their first session come back at a completely different rate than people who visit fewer. Depth on day one is almost the whole story. Second: the best users I've gotten so far didn't come from launches — they came from search. Someone typed a worry into Google, landed in a room, made their own room, and wrote the thing they couldn't say elsewhere.&lt;/p&gt;

&lt;p&gt;I opened the English side of Noding this week. It's quiet — a handful of rooms, a few dozen posts — but alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question I actually want answered
&lt;/h2&gt;

&lt;p&gt;Does "rooms that die" feel right to you, or unsettling? And does path-as-identity read as privacy, or as &lt;em&gt;nothing to hold onto&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;If you want to poke at it, it runs in the browser with no signup: &lt;a href="https://noding.app/en?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=story" rel="noopener noreferrer"&gt;noding.app/en&lt;/a&gt;. I'm the only person building it, so I'll read everything.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>sideprojects</category>
      <category>node</category>
    </item>
  </channel>
</rss>
