<?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>Forem</title>
    <description>The most recent home feed on Forem.</description>
    <link>https://forem.com</link>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed"/>
    <language>en</language>
    <item>
      <title>A Secret I Will Never Reveal</title>
      <dc:creator>Joseph Boone</dc:creator>
      <pubDate>Fri, 15 May 2026 02:17:23 +0000</pubDate>
      <link>https://forem.com/tavari/a-secret-i-will-never-reveal-pf1</link>
      <guid>https://forem.com/tavari/a-secret-i-will-never-reveal-pf1</guid>
      <description>&lt;h2&gt;
  
  
  My Secret:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I may or may not know the exact way to release the GIL on python 3.10+&lt;/p&gt;

&lt;p&gt;I might also know how to recreate this minimally and easily without C extensions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's not a magic trick, or some weird off beat code that doesn't work. &lt;/p&gt;

&lt;p&gt;It functional, typed, code. What it really &lt;em&gt;is&lt;/em&gt; I'll never actually reveal directly. Because &lt;em&gt;I already did&lt;/em&gt; by releasing &lt;a href="https://github.com/TavariAgent/Py-TokenGate" rel="noopener noreferrer"&gt;TokenGate&lt;/a&gt;, the abstraction itself is simple readable and traceable in that codebase. (Once you see it, you know why.) &lt;/p&gt;

&lt;p&gt;When I first unlocked the GIL I tested it and traced the exact requirements. You can do it with or without serialization (serializing makes it easier for obvious reasons once you know but the physics doesn't change). Threading can output ~45x operations across 32 workers on my system in varied normal task distributions. Take a look at these results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Wave   Tokens    OK      Fail    Time      Tok/s     Lat(ms)   Conc    Overlap
1      4         4       0       0.003s    1386.2    0.721     1.00×   1.44×
2      8         8       0       0.003s    2391.2    0.418     1.72×   2.48×
3      16        16      0       0.006s    2744.8    0.364     1.98×   4.82×
4      32        32      0       0.011s    2812.7    0.356     2.03×   11.32×
5      64        64      0       0.022s    2880.0    0.347     2.08×   22.01×
6      128       128     0       0.044s    2907.6    0.344     2.10×   29.78×
7      256       256     0       0.090s    2846.8    0.351     2.05×   37.98×
8      512       512     0       0.182s    2811.5    0.356     2.03×   41.81×
9      1024      1024    0       0.364s    2813.9    0.355     2.03×   44.18× &amp;lt;-
10     2048      2048    0       0.775s    2644.3    0.378     1.91×   44.86× &amp;lt;-
11     4096      4096    0       1.454s    2816.3    0.355     2.03×   38.34×
12     8192      8192    0       2.905s    2819.9    0.355     2.03×   32.64×
13     16384     16384   0       5.925s    2765.0    0.362     1.99×   27.92×
14     32768     32768   0       12.102s   2707.7    0.369     1.95×   24.96× &amp;lt;-
15     65536     65536   0       23.494s   2789.5    0.358     2.01×   24.21× &amp;lt;- 

Wave 9+10, 1024-2048 tasks at any given moment = 40+ times faster

Wave 14 + 15, Massive overload and still holding GIL free status.

TOTAL  131,068   131,068  0      89.091s
Avg latency : 0.386 ms/token
Peak overlap: 44.86×
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;All tokens submitted instantly per-batch.&lt;/em&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;I'll just say this: There are domains, there is physics, the CPU must obey these. So think about that and read TokenGate.&lt;/p&gt;

&lt;p&gt;(Bonus hint: There is exactly 3 components required to unlock the GIL.)&lt;/p&gt;

</description>
      <category>python</category>
      <category>code</category>
      <category>opensource</category>
      <category>performance</category>
    </item>
    <item>
      <title>AI 週報 — 2026-05-08 to 2026-05-15 | OpenAI 做顧問、Anthropic 做生態，模型公司集體轉向</title>
      <dc:creator>Yang Goufang</dc:creator>
      <pubDate>Fri, 15 May 2026 02:10:50 +0000</pubDate>
      <link>https://forem.com/yang_goufang_23c7ba674984/ai-zhou-bao-2026-05-08-2026-05-15openai-zuo-gu-wen-anthropic-zuo-sheng-tai-mo-xing-gong-si-ji-ti-zhuan-xiang-n81</link>
      <guid>https://forem.com/yang_goufang_23c7ba674984/ai-zhou-bao-2026-05-08-2026-05-15openai-zuo-gu-wen-anthropic-zuo-sheng-tai-mo-xing-gong-si-ji-ti-zhuan-xiang-n81</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;本週一句話：OpenAI 正在變成一家顧問公司，Anthropic 正在變成一家平台公司——兩者都不約同時放棄了「模型即產品」的故事。&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  模型公司集體轉向：從 API 銷售到制度性資源
&lt;/h2&gt;

&lt;p&gt;140 億美元——這是 OpenAI 對其新建「Deployment Company」的估值，聲稱來自同一週的外部融資談判&lt;a href="https://news.google.com/rss/articles/CBMickFVX3lxTE95QnZPQkxzLW9WdHJLbUplMUo3dHgyY0JSNmJfdkRzdXlaU2ZUdGw2VEFyM3NXQ1VNYTBqR3Jnem5DQk9MV3NQZm5MM3NtbVo3d19xNlhsWnNkMFFaTGhkZDVrZmJOZTVObzBKOGZQbmd4Zw?oc=5" rel="noopener noreferrer"&gt;OpenAI launches the OpenAI Deployment Company to help businesses build around intelligence - OpenAI&lt;/a&gt;&lt;a href="https://news.google.com/rss/articles/CBMicEFVX3lxTE51QUtsM0czTWtzWXBfMEw2amtqdEhOUFlDNUh4UXRtYmM2VUZRQ0NiQXVMclBnSE9tM0t5SWwwTVBRZUx4WWVkNGJFVDdncVZwRURnOVlyYmFKZkZYYVBGZnE3bE9VRnAyVzQyVzFzbjU?oc=5" rel="noopener noreferrer"&gt;OpenAI launches AI consulting arm valued at $14 billion - Axios&lt;/a&gt;。對比之下，支撐這家公司估值基礎的旗艦 API 業務從未獲得過這樣的外部估值肯定。市場在告訴 OpenAI：你最值錢的資產不是模型，是交付能力。&lt;/p&gt;

&lt;p&gt;5/11 OpenAI 宣佈成立 Deployment Company，同日 Axios 報導該部門估值。同一時間，OpenAI 營收負責人 Dresser 對 CNBC 表示企業 AI 採用已達「臨界點」，但他所指的不是需求爆發，而是&lt;strong&gt;交付複雜度&lt;/strong&gt;&lt;a href="https://news.google.com/rss/articles/CBMifEFVX3lxTE56YkNzZ0NCdElkekVKSncwNVY2WmlBQzd1S3pvSkYxOXNFdW52MWN6MHFQV21sa0FaLVJqbEl0Zm9OczQ2ZGI4cVM1SFowenMyYzNKb3RydjBWNE1NNV9NUi1sZk9BZFlra3FrNUo0RUU5VWhpNVpJX2RYamrSAYIBQVVfeXFMT2RQNWJ3OC1vbGFKLWVWekdWNl9pc1htREFvRXBKUFNjM1NTWHpMb0RPMlkxOXZEUW1kYWZ4MDVTeGhMbjdYbFBlVG9jdk8xNWplRnliMmtxUnktS25tTTZjOGhfXzk2djI4UEJXRHBuTkhleGIzUXVlN1BfRjVjNUN0QQ?oc=5" rel="noopener noreferrer"&gt;OpenAI revenue chief Dresser says enterprise AI adoption is 'at a tipping point' - CNBC&lt;/a&gt;。這與 Accenture Federal Services 的聯邦政府合作（涉及安全合規與法規約束）和 Fiserv 的金融機構合作形成同一敘事：企業要的不是 API，而是有人幫他們把 API 變成合規、可靠、可解釋的系統&lt;a href="https://news.google.com/rss/articles/CBMixgFBVV95cUxPbjFnd0JPT1JzcGRGbThyUm9MWUJxeUtVbGJycmNRUl9YVDZYSktBaFh0XzVicU1zMDA1ZzN4T1JLRmpOSGJsUUJocjZHUXY2SThrcmlHYjNiLVJ3VGE4dVVKZ1RxdlNRaGJvaDJvLXJRM18wZVZ3ZkpkZkRIOEpweFMzODNzMEhjcXBKWE5xN25TTWEwdl9IZGh4bmRRek1MMmZJdnpEd2lMSXhGTUxGQWRjdXZidGREYkZIZ0lCbThKakdQamc?oc=5" rel="noopener noreferrer"&gt;Fiserv Forms Strategic Collaboration with OpenAI to Bring AI to How Fiserv Serves Financial Institutions - Fiserv&lt;/a&gt;&lt;a href="https://news.google.com/rss/articles/CBMi4wFBVV95cUxPMXVOODM4dTQxa1dicnZpTWJpcXJ1T0dEd2FUaDM2Mi1FNDVsOVZhWnZONW1pX0UwQ2xJdGVNUzQwTUZDRnVpYUJZLVAwbjg2YkF2U0EzVnpNVUVkc04wQnFmQkNneEhJX0dKUlRsVnM5MFkzdnJ5T0YtbHZSOG5VQkpSSG1RbGs0blpTbjl4S0Q0NW1qeGplYVJlVjF1MHhpMHVRbVBYLU5KaEtCRUpONDFCeXNYdzJVenNyZUtoUVVzVzNHbDdIeXFSVm5LVUdIUnFwZmk1ZlRWYTFadjNWekpmdw?oc=5" rel="noopener noreferrer"&gt;Accenture Federal Services and OpenAI Partner to Accelerate Secure AI Adoption Across the Federal Government - Accenture&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;Anthropic 的回應則是另一條路：&lt;strong&gt;生態鎖定&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;本週 Anthropic 發布 Claude for Small Business&lt;a href="https://news.google.com/rss/articles/CBMiZ0FVX3lxTFBaaGlNU1BTa0ZESnJCcWhQVnB6anhtUDJOU28wYVhGTEJNcnNUbWdIeFRyUGpzMkFhR0dMbmg5Y2lCa3JHcDBmQ1NGYnZRcjJhOWdMMHVHUHp1V2dmZmtRcU9qTVpCOXM?oc=5" rel="noopener noreferrer"&gt;Introducing Claude for Small Business - Anthropic&lt;/a&gt;，瞄準過去被忽略的中小型市場；同時與 AWS 深度整合推出 Claude Platform——原生透過 AWS 帳戶部署，打通了企業既有雲端基礎設施的信任鏈&lt;a href="https://news.google.com/rss/articles/CBMizgFBVV95cUxQUmZxSGR3dWhwMkRBNVgwSl91ZFVRLVptdTVhUERmcmF3dVROU21WT2hTeGExWldvNDBpN2RaNDY5MmxEa1llWGozcGRsZmNOeFJVLUFhVXoyYTlKMFhmWjc1dmRIckEyZVk4aTlGUk1jNGpuc2ZrMkhMN2xYRDM1dzBfWXN1SmtsRjRxaXJmYWtsMFJCb01UcEJkOWs2NEZGdWVhUjhmaktkLURIS0pnRzRham9JTldWNUREVmRLRERVNG1CLU5pSlBHbks2QQ?oc=5" rel="noopener noreferrer"&gt;Introducing Claude Platform on AWS: Anthropic’s native platform, through your AWS account - Amazon Web Services (AWS)&lt;/a&gt;。更值得注意的是同週的 &lt;strong&gt;20+ 法律領域連接器與 12 個實務插件&lt;/strong&gt;發布&lt;a href="https://news.google.com/rss/articles/CBMi2AFBVV95cUxOX19KNVMwRHMyM2lxaTlPMzExMjlIN21ZSldsVUo0RUVtVFFuYmV0S29DMmRtNDdsRjRnUWg3OFpJenRManVRVGhSaThlTUFKQnJPZUVUdGxwaF9URi1fd1dadkRIbG1CeGoybzdINGFUYjl5VjdhbGJxazNlTnBwY0taTlk3dUptdkZLU25PYzNqRTVsejhmRXVUelJtQWpubDNiemt2ekliMnY2RnBCWmQ1cHRMcjJRUEpmLXN0NTR6R2J5dVpRODF0RThkLW9Cb2Y0Q2pHNGY?oc=5" rel="noopener noreferrer"&gt;Anthropic Goes All-In on Legal, Releasing More Than 20 Connectors and 12 Practice-Area Plugins for Claude - LawSites&lt;/a&gt;，覆蓋電子發現、合同分析、監管合規等具體場景。這不是通用能力，這是&lt;strong&gt;行業知識的制度化&lt;/strong&gt;。&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;OpenAI&lt;/th&gt;
&lt;th&gt;Anthropic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;本週重心&lt;/td&gt;
&lt;td&gt;顧問服務（Deployment Company, $14B 估值）&lt;/td&gt;
&lt;td&gt;生態鎖定（AWS 原生整合、法律插件）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;商業邏輯&lt;/td&gt;
&lt;td&gt;把技術變成可交付的專案&lt;/td&gt;
&lt;td&gt;把模型變成可嵌入的工作流程&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;風險&lt;/td&gt;
&lt;td&gt;毛利率被服務業務稀釋&lt;/td&gt;
&lt;td&gt;垂直場景遷移成本高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Apple × OpenAI 裂痕：整合紅利的消散
&lt;/h2&gt;

&lt;p&gt;Bloomberg 本週報導 Apple 與 OpenAI 的聯盟正在惡化，可能走向法律糾紛&lt;a href="https://news.google.com/rss/articles/CBMiswFBVV95cUxNVTFQQWIwbUlnN3hVWXlZYmpZVnl6aUZPTTU4MWNldVhKdjZ6M2t0ckpGTnEybFltYzJzY2FKa0RKVnBsLWxYaTlYTEZKb19oVkZpc2ZCTjBZaHYzU29jTWZ2OGtQbmczRHNxMm93SUlYX0NvQWZ5T1FTYTRKQkUxZkhOaUdwSlVtNkdpYS1Vd3IxSE4zd3FnVnNFNFJfVElCZXo3RWNPSVQwS1dxdTZ3TWxjbw?oc=5" rel="noopener noreferrer"&gt;Apple-OpenAI Alliance Frays, Setting Up Possible Legal Fight - Bloomberg.com&lt;/a&gt;，Reuters 午後跟進證實 OpenAI 正在探詢法律選項&lt;a href="https://news.google.com/rss/articles/CBMisAFBVV95cUxNNlZZbWlPQmhLZEJnNXM3Yy1rLTdsUkg2NE5KMVhOejMyUERySElSNlVaVTMyeGQ5bTRTWEt3M2lManU0U2p0a2tVaVZVdGQzSC0yV0ozY0E3REN0QWpRTzRPbVdndTlael9JVW0yaGVXOFo1RnJSbm0weHZBaHBIaTFlQXRfbGVHY2MyRW5RdGRJZF9nU1VXeC16V3Z5RXQ3QTFEMDFOd1l1V0NjdDlTbA?oc=5" rel="noopener noreferrer"&gt;OpenAI explores legal options against Apple, source says - Reuters&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;這個裂痕印證了一個結構性問題：&lt;strong&gt;把 AI 整合進 OS 層並不能創造持久的差異化&lt;/strong&gt;。Apple 需要差異化，OpenAI 需要分發，雙方的利益在蜜月期重疊，但當分發問題解決後，Apple 發現自己並沒有因此獲得比競爭對手更多的模型能力——用戶要的是 AI 本身，不是「蘋果牌 AI」。&lt;/p&gt;

&lt;p&gt;對工程决策者的啟示：整合並不能創造護城河。選擇整合夥伴時，需要問的是「誰控制模型迭代的節奏」，而不是「誰的設備跑得最快」。&lt;/p&gt;




&lt;h2&gt;
  
  
  Anthropic 的長期策略：2028 場景與 Gates 合作
&lt;/h2&gt;

&lt;p&gt;Anthropic 本週同時發布兩個長期框架文件：與 Bill Gates 基金會的 &lt;strong&gt;2 億美元合作&lt;/strong&gt;&lt;a href="https://news.google.com/rss/articles/CBMia0FVX3lxTE1UT25PT2ZVemEyNW5mY0RnYjlHa0NhUGw4cVlZWUNaaDdySnRMMXZXZVJMcHRKN25kRzBsVzNINFhUSHhmTGI4MU5JUDEtUVFLcEktM1VvbUZCc1RKUkhwcTFWY3gyWEdQMGZN?oc=5" rel="noopener noreferrer"&gt;Anthropic forms $200 million partnership with the Gates Foundation - Anthropic&lt;/a&gt;，以及「2028：全球 AI 領導力的兩個場景」報告&lt;a href="https://news.google.com/rss/articles/CBMiY0FVX3lxTE1sT0RLX2s1V19uaTlfN0w3NkhVX21TSEo3ZVR4VS10cEoxSThUT3dBR0NZTEptU0VIcERGcXB5SFZ3T1lPN1VxX1dTVngxVU55MEI3NzNWNm9PdFI4V1ZpVUlITQ?oc=5" rel="noopener noreferrer"&gt;2028: Two scenarios for global AI leadership - Anthropic&lt;/a&gt;。前者是資源佈局，後者是話語權佈局。&lt;/p&gt;

&lt;p&gt;2 億美元的 Gates Foundation 合作具體內容未完全透明，但結合近期 Anthropic 在安全與治理方向的發文節奏，判斷這筆資金主要流向 &lt;strong&gt;AI safety research 與全球健康/發展領域的應用&lt;/strong&gt;，而不是產品研發。這意味著 Anthropic 正在建立一個比商業產品更寬廣的敘事框架：自己是能與主權國家、基金會、學術界對話的制度性玩家，而不只是一家模型 API 公司。&lt;/p&gt;

&lt;p&gt;「2028 場景」報告則試圖定義 AI 發展的路徑框架——這是一種&lt;strong&gt;敘事搶位&lt;/strong&gt;，搶在監管機構和政策制定者之前建立對話框架。類似的策略可見於過去制訂 AI 倫理指南的各大廠，但 Anthropic 選擇用「十年預測」而非「原則宣言」的形式，語言更模糊但射程更遠。&lt;/p&gt;




&lt;h2&gt;
  
  
  Codex Windows 沙箱：安全不是功能，是成本
&lt;/h2&gt;

&lt;p&gt;OpenAI 本週發布了兩篇關於 Codex 在 Windows 上安全部署的技術文章&lt;a href="https://news.google.com/rss/articles/CBMiWkFVX3lxTE1kczJ5ZkJycGgxS2NZVDhvMTAzd2M2MlVWOTdLSUhJUkhZMHhYVEluQVlRbE9VMFU5dlBoM25kaGRPcFFYbFltb3QyMTM4NGxzU19DWDlST1ZOdw?oc=5" rel="noopener noreferrer"&gt;Running Codex safely at OpenAI - OpenAI&lt;/a&gt;&lt;a href="https://news.google.com/rss/articles/CBMiZ0FVX3lxTE4wMlR1RTU1M3ZSMkpvdWtPY0t2R2hTVUJ3ZG5WcmlkSl9jdlZucE91TWdWRmViSDkwN2MtRkVjWFpQQlJFcktYTHJJc1dmLUROMU1yWnhaYjAyZDQtb0VDbmNlSHRYbW8?oc=5" rel="noopener noreferrer"&gt;Building a safe, effective sandbox to enable Codex on Windows - OpenAI&lt;/a&gt;，聚焦於如何建立一個安全的沙箱環境讓 AI 代理在企業 Windows 環境中執行代碼。&lt;/p&gt;

&lt;p&gt;微軟企業環境的高度特權狀態與 AI 代理的不可預測行為之間存在根本矛盾。OpenAI 的回應是「我們會建一個隔離層」——這意味著當模型要進入企業工作流程，代碼執行安全不再是可選功能，而是必須計入部署成本的剛性需求。目前企業在評估 AI 供應商時，沙箱建置成本往往未被獨立列出，而這筆成本正好衡量了「模型能力」與「交付能力」之間的真實距離。&lt;/p&gt;

&lt;p&gt;對 CTO 的問題：如果你的供應商告訴你需要自建沙箱環境才能安全使用他們的模型，這筆工程成本算進去了嗎？&lt;/p&gt;




&lt;h2&gt;
  
  
  監管壓力：法律向量正在加速累積
&lt;/h2&gt;

&lt;p&gt;Sam Altman 本週在馬斯克訴訟中作證&lt;a href="https://news.google.com/rss/articles/CBMikgFBVV95cUxNWjJhaUZZZENCZ2JQdEU2eDlJeVhlSnpUa2RPWXFnWmhTNVFhZV9RZnNreWNCck92MExZTENqbnhvY2xKUFR4ZHVlMTdzeXZvb0o2UlM4aXMyODczQnlsZGpzWDFrT1E2eEFMM1VoalVzd1BzVi1UV0cyMHBQYnZTYXc5MXZSejhaN3hHT09ZbzFidw?oc=5" rel="noopener noreferrer"&gt;OpenAI’s Sam Altman takes the stand to fend off Elon Musk’s accusations he ‘stole a charity’ - NPR&lt;/a&gt;，以及針對 OpenAI 的 wrongful death 集體訴訟正測試新的訴訟策略&lt;a href="https://news.google.com/rss/articles/CBMiiAFBVV95cUxOcF9BWnVjNHBqSUJ0a1NLcHlKR1NwSW9yQjVrVENOZU1aYThfeWZqc3ZyZU5XS19NcVRnUmRRRklvVVR3cU5jU1NEcExfMnBCVG51WmJlb0c4dDFQN1pLd0hWTXVDMlJUQmk3YllGUWVaWTVleGRScFFMN0pZMnJLZ0cxMl8zc3lk?oc=5" rel="noopener noreferrer"&gt;Wrongful Death Lawsuits Against OpenAI Test a New Strategy - The New York Times&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;集體訴訟策略的「新」在於它不是專利侵權或契約違約，而是嘗試用&lt;strong&gt;侵權法框架&lt;/strong&gt;追究 AI 的決策後果。如果這種訴訟路徑在未來能建立任何程度的先例，將對所有 AI 廠商的產品發布決策產生深遠影響——不只是 OpenAI 受傷。&lt;/p&gt;




&lt;h2&gt;
  
  
  一個被低估的技術動態：指標式 UI 實驗
&lt;/h2&gt;

&lt;p&gt;本週 Google DeepMind 發布 research 提出「重新想像滑鼠指標」的具體問題&lt;a href="https://news.google.com/rss/articles/CBMiUkFVX3lxTFBHRGNqaEY2Z1g3Z3lBaDBPT05Ra2V0aEVfQ0QtSVFLNjl4Qno4UWNfOWdRMjVKeFFPbUVncDdHamNuM0dhZTc5N2FpZTRJQUZ3NlE?oc=5" rel="noopener noreferrer"&gt;Shaping the future of AI interaction by reimagining the mouse pointer - Google DeepMind&lt;/a&gt;：在多模態模型時代，人與 AI 的互動介面是否仍然需要服從 1960 年代設計的 WIMP 範式（Windows, Icons, Menus, Pointer）？&lt;/p&gt;

&lt;p&gt;這組 research 目前停留在發布階段，距離可用產品至少還有一個 major revision cycle，但它暗示了 Google 對未來人機介面的長期赌注——&lt;strong&gt;感知驅動的界面重設計&lt;/strong&gt;。如果未來誰能重新定義指標誰就能定義下一代 UI 標準，那麼模型能力的競爭將被介面競爭取代，而介面標準的制訂權屬於制度性玩家，不屬於純技術團隊。這個框架與本週 OpenAI 和 Anthropic 的走向形成呼應：硬體與模型的發布節奏正在被制度和整合速度追上。&lt;/p&gt;




&lt;p&gt;本週結論：OpenAI 發現自己最值錢的資產不是模型而是部署能力，Anthropic 發現自己最深的護城河不是能力而是行業知識的封裝速度。兩個方向都指向同一個結論：&lt;strong&gt;AI 的下一個瓶頸不在於模型有多強，而在於誰能最快把模型變成工作流程中不可繞過的一環&lt;/strong&gt;。&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>tech</category>
      <category>llm</category>
    </item>
    <item>
      <title>Silicon Holler: What Happens When the Brain Drain Finally Stops</title>
      <dc:creator>Marsulta</dc:creator>
      <pubDate>Fri, 15 May 2026 02:07:40 +0000</pubDate>
      <link>https://forem.com/marsulta/silicon-holler-what-happens-when-the-brain-drain-finally-stops-52f4</link>
      <guid>https://forem.com/marsulta/silicon-holler-what-happens-when-the-brain-drain-finally-stops-52f4</guid>
      <description>&lt;p&gt;&lt;em&gt;An Appalachian builder's case for why the next great tech hub is hiding in plain sight&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;There's a thing that happens in Eastern Kentucky.&lt;/p&gt;

&lt;p&gt;You grow up sharp. You figure things out. You see patterns other people miss, build things from nothing, solve problems with whatever's in reach. And then, if you're ambitious enough, you leave. You have to. Because the message this place has sent for generations is that the good stuff happens somewhere else.&lt;/p&gt;

&lt;p&gt;Silicon Valley. Austin. Boston. Seattle. The coasts are where you go if you want to matter.&lt;/p&gt;

&lt;p&gt;That's the brain drain. It's not a news story or a policy problem or an abstraction. It's personal. It's the smartest people in your county packing up and leaving because the county doesn't have anything for them.&lt;/p&gt;

&lt;p&gt;And the data backs it up. The Appalachian Regional Commission found the region grew just 4.0% from 2010 to 2023, compared to 7.8% nationally. The Appalachian portions of West Virginia, Ohio, New York, Virginia, and Mississippi each lost at least 3% of their populations. In some distressed counties, the damage is generational -- research found that places like McDowell County, West Virginia lost roughly 25% of their young adult population through net outmigration, with college-educated residents leaving at a 29% net rate.&lt;/p&gt;

&lt;p&gt;Every smart person who leaves makes it a little harder for the next one to stay.&lt;/p&gt;

&lt;p&gt;I'm an addictions counselor in Eastern Kentucky. I'm also a solo developer who, with no CS degree, no funding, and no team, built an AI orchestration engine that 44 funded teams independently decided needed to exist. I named it Orca. I shipped v1.0.0 in late 2025.&lt;/p&gt;

&lt;p&gt;I didn't leave.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Research Actually Says
&lt;/h2&gt;

&lt;p&gt;Before I make the case, I want to be honest about something: the brain drain in Appalachia is not a single uniform thing. The ARC's own data shows a bifurcated region. Southern Appalachia grew 13.2% over the same period the rest of the region stagnated. The outmigration crisis is concentrated in distressed, rural, Central and Northern Appalachia -- places like Eastern Kentucky, southern West Virginia, and parts of Ohio.&lt;/p&gt;

&lt;p&gt;That distinction matters. It means this isn't a story about a dying region. It's a story about a region with a widening internal divide, where some parts are thriving and others are still bleeding out the people they can least afford to lose.&lt;/p&gt;

&lt;p&gt;The research on &lt;em&gt;why&lt;/em&gt; people leave is equally clear. A peer-reviewed study of Central Appalachian students found the strongest predictor of wanting to stay wasn't love of home or cultural identity -- it was the perceived likelihood of finding an interesting job with good salary and advancement opportunities. Partner employment and access to continued education also mattered. The policy implication the researchers drew was blunt: stronger public-private partnerships that create real jobs matter more than rhetoric about place loyalty.&lt;/p&gt;

&lt;p&gt;In other words, people will stay if there's something worth staying for.&lt;/p&gt;

&lt;p&gt;That's the opening.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Structural Advantages Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;When people think about building tech in Appalachia, they think about what's missing. The venture capital, the density, the ecosystem. Those gaps are real. But the cost structure tells a different story.&lt;/p&gt;

&lt;p&gt;Bureau of Economic Analysis regional price parity data shows that Appalachian metros operate at a fraction of what the major tech hubs cost. Huntington-Ashland comes in at 88.4 on the all-items index (national average is 100). Lexington sits at 93.1. Pittsburgh at 94.4. Compare that to Boston at 111.6, Seattle at 113.0, and San Francisco at 118.2.&lt;/p&gt;

&lt;p&gt;On housing specifically, the gap is staggering. BEA data shows housing price parity values of 50.0 for Huntington-Ashland and 74.4 for Lexington -- compared to 148.2 for Boston, 151.5 for Seattle, and 200.2 for San Francisco. That's not a slight discount. That's a fundamentally different cost basis for building a company.&lt;/p&gt;

&lt;p&gt;The labor cost differential mirrors it. BLS data shows mean hourly wages for software developers running $181,220 annually in San Francisco and $164,130 in Seattle. The interior U.S. operates at a materially lower baseline -- which means a tech employer can hire five serious engineers in Appalachia for what one costs in the Bay Area. That's not a small thing. That's a structural advantage that compounds over a decade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Land and power.&lt;/strong&gt; Data centers need physical footprint and power infrastructure. Eastern Kentucky has both, at prices California can't touch. The buildout that AI infrastructure requires is going to happen somewhere. The question is who captures that value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loyalty.&lt;/strong&gt; When someone who grew up here gets a real shot at building something meaningful in their own backyard, the calculus flips. Research on the Tulsa Remote program -- which offered relocation incentives to remote workers -- found it increased community engagement, entrepreneurship, and long-term willingness to stay. A Brookings evaluation found that work-from-anywhere policies can help reverse brain drain to large cities while increasing workers' real income and community connection. The lesson wasn't that cash alone works. It was that cash plus curation, community-building, and a credible local narrative can work. Appalachia has the narrative. It needs the jobs to back it up.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Infrastructure Is Further Along Than You Think
&lt;/h2&gt;

&lt;p&gt;One of the persistent myths about Appalachia is that it's a digital dead zone. The reality is more nuanced.&lt;/p&gt;

&lt;p&gt;ARC data shows 86.2% of Appalachian households had broadband subscriptions in 2019-2023, up 11.1 percentage points from the previous period. Device access reached 92% of households. The gaps remain -- 116 Appalachian counties still had broadband subscription rates below 80%, almost all of them rural and outside metro areas -- but the trend line is moving in the right direction.&lt;/p&gt;

&lt;p&gt;The ARC itself has been building the ecosystem infrastructure for years: entrepreneurship academies, STEM academies, workforce development programs, energy transition initiatives, and broadband investment portfolios that have aimed to serve 500 communities and 70,000 households. Kentucky's SOAR organization serves all 54 ARC counties in Eastern Kentucky, explicitly focused on the "deep-seated issue of population retention and growth." West Virginia launched Ascend WV, a remote-worker attraction program that has generated 90,000 applications and welcomed 1,400 individuals from 48 states and eight countries.&lt;/p&gt;

&lt;p&gt;The pieces exist. They're just not yet assembled into something coherent enough to create the conditions where a young engineer or founder looks around and thinks: &lt;em&gt;I can build a full life here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's the gap. And it's closeable.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Silicon Holler Actually Means
&lt;/h2&gt;

&lt;p&gt;I'm not talking about a marketing campaign. I'm not talking about a "tech district" on a render.&lt;/p&gt;

&lt;p&gt;I'm talking about what happens when the jobs exist, the broadband works, the partner can find employment, and the kid who's too smart for the options in front of them doesn't have to choose between ambition and home.&lt;/p&gt;

&lt;p&gt;The research says something important about this: the best model for Appalachian tech formation isn't a single winner-take-all city. It's a distributed hub -- a few anchor metros and university nodes linked to lower-cost surrounding counties, with remote-work pathways, local coworking infrastructure, and targeted sector bets. Not a Bay Area clone. Something that fits the actual geography and the actual talent pool.&lt;/p&gt;

&lt;p&gt;That fits exactly how I think about this. You don't need everyone in one building. You need the work to be real, the pay to be fair, and the infrastructure to hold.&lt;/p&gt;

&lt;p&gt;My core mission with Orca and everything I'm building under Yak Stacks is making high-quality AI accessible to people who've been priced out of it. That mission and this place are the same mission. Eastern Kentucky has always been on the outside of economic power. I know what it feels like to not have access to the good tools. That's not abstract for me.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Region Actually Has
&lt;/h2&gt;

&lt;p&gt;People talk about Appalachia like it's a problem to be solved. A place of deficits.&lt;/p&gt;

&lt;p&gt;That's a real part of the story. But it's not the whole story.&lt;/p&gt;

&lt;p&gt;Eastern Kentucky gave the world coal that powered the industrial revolution. Bourbon that became a global industry. Bluegrass that influenced every genre of music that followed. This region has always produced things the world needed. It just never got credit and never captured the value.&lt;/p&gt;

&lt;p&gt;Educational attainment has been rising -- 27.3% of Appalachian adults held at least a bachelor's degree in 2019-2023, up 3.1 percentage points in five years. Central Appalachia still sits nearly 20 points below the national average, which is a real gap, but the direction is clear. The talent pipeline is being built. The question is whether it empties into San Francisco again or builds something here.&lt;/p&gt;

&lt;p&gt;The research on talent retention says the same thing over and over: people will stay if the job is interesting, the pay is real, the advancement is possible, and the community feels like it has a future. None of those things require a zip code that starts with 9.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Path
&lt;/h2&gt;

&lt;p&gt;Every great tech hub started with one person who proved it was possible.&lt;/p&gt;

&lt;p&gt;Orca is a proof of concept that this kind of work can come from here. That the architecture doesn't care where you're sitting when you write it. That quality gating, multi-agent orchestration, and typed protocol design can come out of Eastern Kentucky as legitimately as they can come out of anywhere else.&lt;/p&gt;

&lt;p&gt;The path from here looks like this: traction leads to credibility, credibility leads to capital, capital creates the conditions where the next person doesn't have to do this alone. Where the next sharp kid in a small Appalachian county has a local ecosystem to plug into instead of a one-way ticket out.&lt;/p&gt;

&lt;p&gt;I'm not claiming to be the person who builds Silicon Holler alone. Nobody does it alone.&lt;/p&gt;

&lt;p&gt;I'm claiming that the conditions are right, the cost structure is real, the infrastructure is building, and the research says it's possible.&lt;/p&gt;

&lt;p&gt;November 28, 2025 is the day we started finding out.&lt;/p&gt;




&lt;h2&gt;
  
  
  To the People Who Already Left
&lt;/h2&gt;

&lt;p&gt;The brain drain wasn't a character failure. It was a rational response to real scarcity. When the job isn't here, you go where the job is. That's not a moral failing -- it's just math.&lt;/p&gt;

&lt;p&gt;But the math is changing. The tools are leveling the playing field faster than the geography can push back. If you left this place carrying something forged here -- the stubbornness, the resourcefulness, the ability to solve problems with whatever's available -- you might find there's something worth coming back for.&lt;/p&gt;

&lt;p&gt;Not because things are perfect. They're not.&lt;/p&gt;

&lt;p&gt;Because what you've always been capable of building doesn't require San Francisco anymore.&lt;/p&gt;




&lt;h2&gt;
  
  
  To the People Who Stayed
&lt;/h2&gt;

&lt;p&gt;You already know what this place has that the coasts don't. The way people here build things from nothing, solve problems with what's available, and keep going when the conditions aren't right.&lt;/p&gt;

&lt;p&gt;Those are exactly the qualities that produce durable technology. Not the pitch deck. Not the pedigree.&lt;/p&gt;

&lt;p&gt;The stubbornness.&lt;/p&gt;

&lt;p&gt;Use it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;James Yarber is the founder of Yak Stacks and the developer of Orca, an open-source AI orchestration engine. He lives and works in Eastern Kentucky.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Appalachian Regional Commission, &lt;em&gt;Appalachia Then and Now: Population Overview&lt;/em&gt; — demographic history, county-level persistence of decline&lt;/li&gt;
&lt;li&gt;ARC Chartbook 2019–2023 — regional population growth (4.0% vs. 7.8% national), educational attainment (27.3% bachelor's degree), broadband subscription rates (86.2%), device access (92%)&lt;/li&gt;
&lt;li&gt;ARC Kentucky FY 2025 — $23.6M in 49 projects, workforce and infrastructure investment&lt;/li&gt;
&lt;li&gt;ARC Broadband Portfolio RFP — 500 communities, 70,000 households, 7,000 businesses served&lt;/li&gt;
&lt;li&gt;Bureau of Economic Analysis, Regional Price Parities 2023 — all-items and housing RPPs for Appalachian metros vs. coastal hubs&lt;/li&gt;
&lt;li&gt;BEA State RPP 2024 — Kentucky 89.9, Tennessee 92.1, California 110.7, Massachusetts 107.7&lt;/li&gt;
&lt;li&gt;Bureau of Labor Statistics, Occupational Employment and Wage Statistics May 2023/2024 — metro wage comparisons, software developer salary benchmarks&lt;/li&gt;
&lt;li&gt;Vazzana &amp;amp; Rudi-Polloshka, peer-reviewed study of Central Appalachian student retention — job quality and advancement as primary retention predictors&lt;/li&gt;
&lt;li&gt;Terman, qualitative research on West Virginia post-coal communities — social identity and institutional support in talent retention&lt;/li&gt;
&lt;li&gt;Kannapel &amp;amp; Flory, review of postsecondary transitions in Central Appalachia — interventions with retention evidence&lt;/li&gt;
&lt;li&gt;Ascend WV program data — 90,000 applications, 1,400 individuals relocated from 48 states&lt;/li&gt;
&lt;li&gt;Brookings Institution / Upjohn Institute, Tulsa Remote evaluations — rural talent attraction, community embeddedness, ROI&lt;/li&gt;
&lt;li&gt;SOAR Kentucky — 54-county mission, population retention and growth focus&lt;/li&gt;
&lt;li&gt;USDA ERS, nonmetro migration post-2020 — national context for rural in-migration trends&lt;/li&gt;
&lt;li&gt;Lichter et al., historical ARC outmigration research — McDowell County data (25% young adult loss, 29% college-educated net outmigration)&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>career</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Stop Paying for Email Verification APIs — A Zero-Cost DNS Approach</title>
      <dc:creator>Rumblingb</dc:creator>
      <pubDate>Fri, 15 May 2026 02:06:35 +0000</pubDate>
      <link>https://forem.com/rumblingb/stop-paying-for-email-verification-apis-a-zero-cost-dns-approach-317</link>
      <guid>https://forem.com/rumblingb/stop-paying-for-email-verification-apis-a-zero-cost-dns-approach-317</guid>
      <description>&lt;h1&gt;
  
  
  Stop Paying for Email Verification APIs — A Zero-Cost DNS Approach
&lt;/h1&gt;

&lt;p&gt;Most email verification APIs charge $0.005-0.01 per check. At 10,000 signups a month, that's $50-100 — before you've made a cent.&lt;/p&gt;

&lt;p&gt;Here's the thing: &lt;strong&gt;you don't need them.&lt;/strong&gt; DNS already has the answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Email Verification Actually Works
&lt;/h2&gt;

&lt;p&gt;When you type &lt;code&gt;user@gmail.com&lt;/code&gt;, three things matter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Syntax&lt;/strong&gt; — is it even a valid email format?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain&lt;/strong&gt; — does &lt;code&gt;gmail.com&lt;/code&gt; have MX records? (DNS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mailbox&lt;/strong&gt; — does &lt;code&gt;user&lt;/code&gt; exist on that server? (SMTP)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 1 and 2 cost you nothing. Step 3 requires an SMTP handshake, but most services skip it anyway — it's slow, unreliable, and many servers don't even respond.&lt;/p&gt;

&lt;p&gt;So 80% of "verification" is just DNS queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  The DNS Trick
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig gmail.com MX +short
&lt;span class="c"&gt;# 10 alt1.gmail-smtp-in.l.google.com.&lt;/span&gt;
&lt;span class="c"&gt;# 20 alt2.gmail-smtp-in.l.google.com.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No MX records? &lt;strong&gt;The domain can't receive email.&lt;/strong&gt; That's a definitive bounce.&lt;/p&gt;

&lt;p&gt;Add a disposable domain check and you've already caught:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typos (&lt;code&gt;gmai.com&lt;/code&gt; → no MX → invalid)&lt;/li&gt;
&lt;li&gt;Disposable inboxes (&lt;code&gt;mailinator.com&lt;/code&gt; → known pattern)&lt;/li&gt;
&lt;li&gt;Non-existent domains (&lt;code&gt;asdfghjkl.com&lt;/code&gt; → NXDOMAIN)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I Built This as an MCP Server
&lt;/h2&gt;

&lt;p&gt;I wanted my AI agents to verify emails without API keys, rate limits, or monthly bills. So I built &lt;a href="https://smithery.ai/servers/vishar-rumbling/email-verify-mcp" rel="noopener noreferrer"&gt;Email Verify MCP&lt;/a&gt; — it runs DNS queries locally and exposes them as MCP tools.&lt;/p&gt;

&lt;p&gt;Any agent (Claude, Cursor, Goose) can call:&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="nf"&gt;verify_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;valid&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="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;has_mx&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="nx"&gt;disposable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key. No rate limit. No cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent → MCP Protocol → Email Verify Server → DNS Resolver
                                              ↓
                                     MX, A, TXT records
                                              ↓
                                     Validation result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server uses Node.js &lt;code&gt;dns.promises&lt;/code&gt; module — no external dependencies, no network calls (except DNS), no third-party API.&lt;/p&gt;

&lt;p&gt;Free tier: 50 verifications/day. Pro tier ($19/mo): 1,000/month. That's $0.019 per check at scale — 2-5x cheaper than commercial APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Shipping This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Build what agents need.&lt;/strong&gt; AI agents are the new power users. They don't care about pretty dashboards — they need programmatic access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS is underrated.&lt;/strong&gt; Most verification problems are DNS problems in disguise. MX records, SPF, DKIM, DMARC — all free to query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP is the distribution channel.&lt;/strong&gt; Instead of building yet another SaaS, I built an MCP server. Now 27 servers on &lt;a href="https://smithery.ai/servers/vishar-rumbling" rel="noopener noreferrer"&gt;Smithery&lt;/a&gt; act as a discovery network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @rumblingb/email-verify-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add it to your Claude/Cursor MCP config:&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;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"email-verify"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@rumblingb/email-verify-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&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;span class="p"&gt;}&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;Stop paying per verification. DNS is free.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building MCP servers at &lt;a href="https://smithery.ai/servers/vishar-rumbling" rel="noopener noreferrer"&gt;smithery.ai/servers/vishar-rumbling&lt;/a&gt;. Follow the build at &lt;a href="https://x.com/rumblingboya" rel="noopener noreferrer"&gt;@rumblingboya&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>devops</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Python and How Python Is Used In The Data Analytics Space. A Beginner's Guide.</title>
      <dc:creator>Joseous Ng'ash</dc:creator>
      <pubDate>Fri, 15 May 2026 02:05:22 +0000</pubDate>
      <link>https://forem.com/josengash/python-and-how-python-is-used-in-the-data-analytics-space-a-beginners-guide-52dh</link>
      <guid>https://forem.com/josengash/python-and-how-python-is-used-in-the-data-analytics-space-a-beginners-guide-52dh</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In today's digital world, data is everywhere, every time people stream movies, socialize on social media, shop online, or make online payments amongst others, data is generated. Institutions collect this type of data to be able to analyze and understands customer behavior to be able to improve services, make better decisions and come up with future predictions depending on the trend.&lt;/p&gt;

&lt;p&gt;The collected data is raw and has little value unless it is processed and analyzed. This brings about &lt;strong&gt;Data Analytics&lt;/strong&gt; which involves collecting, cleaning, transforming and interpreting data to uncover useful insights.&lt;/p&gt;

&lt;p&gt;To be able to perform data analytics processes, the analysts rely on programming tools and one of the most used programming language in data analytics is &lt;strong&gt;Python.&lt;/strong&gt; It has become a favorite among beginners and professionals because it is simple to learn, powerful and supported by rich ecosystem of libraries designed for data analysis.&lt;/p&gt;

&lt;p&gt;This article will cover what is python, why it is widely used in data analytics, the key libraries every beginner should learn, how it helps in cleaning and analyzing data and why python is the best choice for professions in data analytics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Is Python&lt;/strong&gt;&lt;br&gt;
Python is a programming language created by &lt;em&gt;Guido Van Rossum&lt;/em&gt; and was first released in 1991.&lt;/p&gt;

&lt;p&gt;Unlike some programming languages that require complex syntax, python uses clean and straightforward commands that resemble plain English.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of python command&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The simple command line displays text on the screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python is known for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large Community support&lt;/li&gt;
&lt;li&gt;Versatility&lt;/li&gt;
&lt;li&gt;Simplicity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Python Is Popular in Data Analytics&lt;/strong&gt;&lt;br&gt;
Python has become one of mostly used tools in data analytics for several reasons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy to Learn and Use&lt;/strong&gt;&lt;br&gt;
Data analysis involves solving business and technical problems. Analyst should focus on understanding data rather than struggling with difficult programming syntax.&lt;/p&gt;

&lt;p&gt;Python's simple structure allows beginners to write meaningful programs easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
Calculating average using python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;avg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The simple structure of python makes it ideal for people transitioning into analytics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Libraries Ecosystem&lt;/strong&gt;&lt;br&gt;
Python provides specialized libraries that simplify data-related task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strong Data Handling Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python can process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unstructured data (text, images)&lt;/li&gt;
&lt;li&gt;Semi_structured data (JSON,XML)&lt;/li&gt;
&lt;li&gt;Structured data (tables, spreadsheets)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flexibility makes it useful across many industries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration with Other Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python works well with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jupyter Notebook&lt;/li&gt;
&lt;li&gt;MS Excel&lt;/li&gt;
&lt;li&gt;MS Power BI&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows analyst to build complete workflows&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High Industry Demand&lt;/strong&gt;&lt;br&gt;
Many companies actively seek python skilled analysts because it helps automate repetitive tasks and process large dataset efficiently.&lt;/p&gt;

&lt;p&gt;Industries using python includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finance&lt;/li&gt;
&lt;li&gt;E-commerce&lt;/li&gt;
&lt;li&gt;Healthcare&lt;/li&gt;
&lt;li&gt;Marketing&lt;/li&gt;
&lt;li&gt;Education&lt;/li&gt;
&lt;li&gt;Telecommunications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Python Libraries Used in Data Analytics.
&lt;/h3&gt;

&lt;p&gt;One of python's greatest strength is its libraries&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;library&lt;/strong&gt; is a collection of pre-written code that performs specific tasks. Some of most important libraries for beginners include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pandas&lt;/strong&gt;&lt;br&gt;
Pandas is the most widely used library for data manipulation and analysis.&lt;br&gt;
It helps analysts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read dataset&lt;/li&gt;
&lt;li&gt;Clean data&lt;/li&gt;
&lt;li&gt;filter rows&lt;/li&gt;
&lt;li&gt;Handle missing values&lt;/li&gt;
&lt;li&gt;Group and summarize data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sales.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loads a CSV file and displays the first five rows.&lt;br&gt;
Pandas is essential for any data analyst.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NumPy&lt;/strong&gt;&lt;br&gt;
NumPy is used for numerical operations.&lt;br&gt;
It is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mathematical calculations&lt;/li&gt;
&lt;li&gt;Working with arrays&lt;/li&gt;
&lt;li&gt;Statistical analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Matplotlib&lt;/strong&gt;&lt;br&gt;
This library is used for creating graphs and charts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It helps analysts visualize trends&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seaborn&lt;/strong&gt;&lt;br&gt;
Seaborn build on Matplotlib and creates more attractive visualizations&lt;br&gt;
It is commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Heatmaps&lt;/li&gt;
&lt;li&gt;Bar charts&lt;/li&gt;
&lt;li&gt;Distribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scikit_learn&lt;/strong&gt;&lt;br&gt;
Although mainly used in machine learning, beginners can use it for predictive analytics.&lt;br&gt;
It support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regression&lt;/li&gt;
&lt;li&gt;Classification&lt;/li&gt;
&lt;li&gt;Clustering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Jupyter Notebook&lt;/strong&gt;&lt;br&gt;
Jupyter notebook allows analysts to write code, visualize results and document analysis in one place.&lt;br&gt;
It is widely used for learning and experimentation.&lt;/p&gt;
&lt;h3&gt;
  
  
  How Python Is Used to Clean, Analyze and Visualize Data.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Data Cleaning&lt;/strong&gt;&lt;br&gt;
Raw data is usually messy, common problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing values&lt;/li&gt;
&lt;li&gt;Duplicates records&lt;/li&gt;
&lt;li&gt;Incorrect formats&lt;/li&gt;
&lt;li&gt;Typographical errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Python helps to clean such problems in data efficeintly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customers.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop_duplicates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inplace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inplace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script removes duplicates and fills missing values.&lt;br&gt;
Cleaning data is important because poor-quality data leads to inaccurate analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Analysis&lt;/strong&gt;&lt;br&gt;
After cleaning the dataset, analysts explore the data to identify patterns&lt;/p&gt;

&lt;p&gt;Python can calculate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Averages&lt;/li&gt;
&lt;li&gt;Totals&lt;/li&gt;
&lt;li&gt;Trends&lt;/li&gt;
&lt;li&gt;Correlations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Revenue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script calculates total revenue by region.&lt;br&gt;
Analysts use such insights to answer business questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which product sells the most&lt;/li&gt;
&lt;li&gt;Which customer segment is most profitable&lt;/li&gt;
&lt;li&gt;Which month generates highest or lowest revenue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data Visualization&lt;/strong&gt;&lt;br&gt;
Visualizations makes insights easier to understanda.&lt;br&gt;
Instead of reading large tables, decision-makers can quickly interpret charts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sns&lt;/span&gt;

&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;barplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Region&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Revenue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a bar chart showing regional revenue.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Python supports:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Line charts&lt;/li&gt;
&lt;li&gt;Pie charts&lt;/li&gt;
&lt;li&gt;Scatter plots&lt;/li&gt;
&lt;li&gt;Histograms&lt;/li&gt;
&lt;li&gt;Heatmaps
Visualization is critical because it helps communicate findings clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Examples of Python in Data Analytics
&lt;/h3&gt;

&lt;p&gt;Python is widely used in real-world organizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-Commerce&lt;/strong&gt;&lt;br&gt;
Online stores analyze customer purchase behaviour&lt;/p&gt;

&lt;p&gt;Python helps answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which product sells most&lt;/li&gt;
&lt;li&gt;Which products are often bought together&lt;/li&gt;
&lt;li&gt;Which customer are likely to return
Companies like &lt;strong&gt;Alibaba&lt;/strong&gt; use data analytics extensively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Finance&lt;/strong&gt;&lt;br&gt;
Banks and financial institutions use python for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer segmentation&lt;/li&gt;
&lt;li&gt;Risk analysis&lt;/li&gt;
&lt;li&gt;Fraud detection
By analyzing transaction patterns, suspicious activity can be detected quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Healthcare&lt;/strong&gt;&lt;br&gt;
Hospitals use python to analyze:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patient records&lt;/li&gt;
&lt;li&gt;Disease trends&lt;/li&gt;
&lt;li&gt;Treatment outcomes
This improves decision-making and patient care&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Marketing&lt;/strong&gt;&lt;br&gt;
Business analyst analyze business performance using python.&lt;/p&gt;

&lt;p&gt;Questions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which audience engages most?&lt;/li&gt;
&lt;li&gt;Which advertisements perform best?&lt;/li&gt;
&lt;li&gt;What is the conversion rate?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sports Analytics&lt;/strong&gt;&lt;br&gt;
Sports teams analyze players or club performance and match statistics. Python helps identify strengths and weaknesses. This helps improve team strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Beginners Should Learn Python.
&lt;/h3&gt;

&lt;p&gt;If you are new to data analytics, python is one of the best starting points.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beginner-Friendly&lt;/strong&gt;&lt;br&gt;
Its syntax is simple and readable.&lt;br&gt;
You can start solving real problems quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strong Career Opportunities&lt;/strong&gt;&lt;br&gt;
Python is highly valued in roles such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Analyst&lt;/li&gt;
&lt;li&gt;Data Scientist&lt;/li&gt;
&lt;li&gt;Business Analyst&lt;/li&gt;
&lt;li&gt;Machine Learning Engineer
Learning python increases employability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Supports Career Growth&lt;/strong&gt;&lt;br&gt;
Once you master Python for analytics, you can expand into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Machine Learning&lt;/li&gt;
&lt;li&gt;Artificial intelligence&lt;/li&gt;
&lt;li&gt;Data Engineering&lt;/li&gt;
&lt;li&gt;Automation
Python opens many career paths.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Practical and In-Demand&lt;/strong&gt;&lt;br&gt;
Python is not just theoretical.&lt;br&gt;
You can immediately apply it to real datasets and projects.&lt;br&gt;
This makes learning more engaging and rewarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In modern data analytics, python has become one of most important tools.&lt;/p&gt;

&lt;p&gt;With python, analyst can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean messy datasets&lt;/li&gt;
&lt;li&gt;Analyze trends and patterns&lt;/li&gt;
&lt;li&gt;Create meaningful visualizations&lt;/li&gt;
&lt;li&gt;Generate actionable business insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Python powers real world data driven decisions across industries such as E-commerce, Finance, Healthcare and sports.&lt;/p&gt;

&lt;p&gt;Learning python as a beginner in data analytics profession provides a strong technical foundation and opens doors to exciting career opportunities in the growing field of data.&lt;/p&gt;

&lt;p&gt;As data continues to shape the future, python remains one of the tools to help analysts transform raw information into valuable knowledge.&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>analytics</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>5 Token-Saving Habits From 3 Months With Claude Code</title>
      <dc:creator>JessYT</dc:creator>
      <pubDate>Fri, 15 May 2026 02:01:32 +0000</pubDate>
      <link>https://forem.com/jessyt/5-token-saving-habits-from-3-months-with-claude-code-41mh</link>
      <guid>https://forem.com/jessyt/5-token-saving-habits-from-3-months-with-claude-code-41mh</guid>
      <description>&lt;h1&gt;
  
  
  5 Token-Saving Habits From 3 Months With Claude Code
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;EDIBLOG · Phase 2-1 · 3-Month Retrospective&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hi, I'm Eddie. After 3 months running blog automations, I settled on 5 token-saving habits. Honestly — &lt;strong&gt;I broke each one at least once before they stuck&lt;/strong&gt;. This is the first deep dive I promised in the &lt;a href="https://docs.claude.com/en/docs/claude-code/memory" rel="noopener noreferrer"&gt;CLAUDE.md memory&lt;/a&gt; index post.&lt;/p&gt;

&lt;p&gt;The 5 habits: &lt;code&gt;/compact&lt;/code&gt;, agent split, &lt;code&gt;/clear&lt;/code&gt;, CLAUDE.md split, 3 Skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  01 — &lt;code&gt;/compact&lt;/code&gt;: press it on the alert, judge by the next answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bottom line.&lt;/strong&gt; I learned &lt;code&gt;/compact&lt;/code&gt; fires when the context alert appears. The way I see it, it summarizes and compresses the conversation to free up token space. It is not lossless.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My take after 3 months:&lt;/strong&gt; "Sometimes I lose things. When critical info disappears, the next answer can go off the rails."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My pattern — see the alert, run &lt;code&gt;/compact&lt;/code&gt;, ask one question, and if it looks wrong I &lt;code&gt;/clear&lt;/code&gt; and restart. &lt;strong&gt;No blind trust.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think being honest about limits is the better move. I accepted that &lt;strong&gt;compaction is not lossless&lt;/strong&gt;. Right after a critical code change, I now habitually restate the key facts before compacting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;See the alert → /compact &lt;span class="o"&gt;(&lt;/span&gt;first attempt&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;[Claude] context window 80% used. /compact recommended.
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/compact
&lt;span class="go"&gt;[Claude] Compaction done — 60% token space recovered.

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Immediate one-line check after compacting
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Show me the contents of [key file] you just worked on"&lt;/span&gt;
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;If clean, &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; If loss detected, /clear and restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  02 — Important work goes to a separate agent, not main
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bottom line.&lt;/strong&gt; The second pattern, in my view, is role separation. I run main Claude as the coordinator and throw detail work to sub-agents.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My separation rule:&lt;/strong&gt; "Anything I consider important — code review, benchmarking, post quality control — doesn't touch main Claude. Dedicated agents only."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I see two payoffs. &lt;strong&gt;Main context stays protected&lt;/strong&gt; + &lt;strong&gt;only the final output of the detail work surfaces back to main&lt;/strong&gt;. The biggest win is that reading a huge document once doesn't eat main context.&lt;/p&gt;

&lt;p&gt;I keep 4 custom agents as one-pager markdown files under &lt;code&gt;.claude/agents/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;monetization-analyst&lt;/code&gt;&lt;/strong&gt; — Monetization analysis — VSD Pro · jessinvestment stage checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;opportunity-ranker&lt;/code&gt;&lt;/strong&gt; — Opportunity ranking — sort next-sequence candidates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dev-finance-explorer&lt;/code&gt;&lt;/strong&gt; — Dev × finance crossover — post idea discovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;asset-health-checker&lt;/code&gt;&lt;/strong&gt; — Asset health check — jobs · blog operations status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of that, there's the &lt;code&gt;/review&lt;/code&gt; slash command and the weekly &lt;code&gt;weekly-blog-review&lt;/code&gt; job (6-AI panel for post quality). This was the single biggest token-saving move.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Don&lt;span class="s1"&gt;'t ask main Claude
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;Task(opportunity-ranker, "rank the next 10 post idea candidates")
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;→ sub-agent works in a separate context, only the result returns to main
&lt;/span&gt;&lt;span class="go"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Main plays coordinator only
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Heavy analysis / 6-AI panels / benchmarking all go to separate agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  03 — &lt;code&gt;/clear&lt;/code&gt;: not compression, full reset
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bottom line.&lt;/strong&gt; Third, I actively use &lt;code&gt;/clear&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My timing rule:&lt;/strong&gt; "When the context completely shifts, I /clear and rebuild from scratch."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A typical example for me — finishing real-estate blog work and switching to debugging the trading system. I realized mixing the two contexts causes incidents.&lt;/p&gt;

&lt;p&gt;I see the two tools as different roles. &lt;code&gt;/compact&lt;/code&gt; is &lt;strong&gt;compress&lt;/strong&gt;, &lt;code&gt;/clear&lt;/code&gt; is &lt;strong&gt;full empty&lt;/strong&gt;. After clear, the first message reloads only CLAUDE.md and I rebuild context from there.&lt;/p&gt;

&lt;p&gt;This was a bit counterintuitive: &lt;strong&gt;clear isn't wasteful — NOT clearing is more expensive in most cases.&lt;/strong&gt; Without clearing, every turn has to spend tokens replaying the entire prior context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/clear &lt;span class="k"&gt;if &lt;/span&gt;you hit ANY of these
&lt;span class="go"&gt;[ ] Complete domain switch (real-estate → trading system, etc.)
[ ] Answer feels off even after /compact (compression loss)
[ ] Conversation getting long, answers slowing down (context bloat)
[ ] Moving to another blog · project (separate CLAUDE.md folder)

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;1+ above → don&lt;span class="s1"&gt;'t hesitate, /clear
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;Clear, reload CLAUDE.md, restart clean
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  04 — Slim CLAUDE.md, move the rest to side files
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bottom line.&lt;/strong&gt; The fourth is the CLAUDE.md diet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;My split rule:&lt;/strong&gt; "Only what's needed every task lives in CLAUDE.md. Everything else is request-specific — that's how you save tokens."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The reason is clear to me. CLAUDE.md is auto-loaded every session. Every line in there spends tokens every time. The conclusion: &lt;strong&gt;anything you rarely look at has to come out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;My actual split structure:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File type&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Main CLAUDE.md&lt;/strong&gt; (auto-loaded every session)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;automation/CLAUDE.md&lt;/code&gt; — ops rules, schedules, incident log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Side files&lt;/strong&gt; (loaded only on request)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;real-estate/_series_guide.md&lt;/code&gt; · &lt;code&gt;ediblog/SKILL.md&lt;/code&gt; · &lt;code&gt;docs/INFRA_2026_05.md&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Archive&lt;/strong&gt; (one-line index only)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CLAUDE-archive-2026-04.md&lt;/code&gt; — old incident log moved out&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I split old incident logs into &lt;code&gt;CLAUDE-archive-2026-04.md&lt;/code&gt; and kept only a one-line index in main. The main file had been swelling past 1,000 lines — you can feel the relief. To me, this is the heart of the main-slim pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Main CLAUDE.md (currently ~80 lines)&lt;/span&gt;

&lt;span class="gu"&gt;## 5. Incident log (learnings)&lt;/span&gt;

| Date | Incident | Action |
|---|---|---|
| 2026-05-09 | 4 publish failures + telegram loop | 4 self-recovery layers added |
&lt;span class="gt"&gt;
&amp;gt; 10 incidents from 2026-04-14 ~ 2026-04-18 moved to `CLAUDE-archive-2026-04.md` §A&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; 8 incidents from 2026-04-21 ~ 2026-05-04 moved to `CLAUDE-archive-2026-05.md` §A&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Main keeps only post-05-05 incidents&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  05 — 3 skills, loaded only on trigger
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bottom line.&lt;/strong&gt; The last one, in my view, is &lt;strong&gt;skills&lt;/strong&gt;. I keep 3 custom skills under &lt;code&gt;automation/.claude/skills/&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;add-launch-job&lt;/code&gt;&lt;/strong&gt; — Auto-triggered when adding a new LaunchAgent job. Checks plist TCC policy · FD limit 3-layer defense. Used heavily this past week alone creating 5 new jobs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;blog-style-guide&lt;/code&gt;&lt;/strong&gt; — Auto-triggered on post writing · review. Applies 9 base patterns + 4 evolved patterns + reviewer gate. Managed in one place across 4 daily-publishing blogs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;captcha-recovery&lt;/code&gt;&lt;/strong&gt; — Auto-triggered on captcha · session corruption. Telegram relay + zombie Chrome cleanup. Rare but mandatory when it hits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I couldn't measure the split effect quantitatively. My read: inline = main CLAUDE.md swells past 1,000 lines and gets fully loaded every session. Split = main keeps a one-line index, and &lt;code&gt;SKILL.md&lt;/code&gt; only loads when triggered. I &lt;strong&gt;estimate ~30% main-token savings&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;~30% main tokens saved&lt;/strong&gt; (estimated, not measured)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 custom skills&lt;/strong&gt; (add · style · captcha)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1 rule-change point&lt;/strong&gt; (one &lt;code&gt;SKILL.md&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog-style-guide&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;9 writing patterns + reviewer gate thresholds for blog post&lt;/span&gt;
  &lt;span class="s"&gt;writing · review · publishing in the automation project. Trigger on&lt;/span&gt;
  &lt;span class="s"&gt;ediblog · jessinvestment · luna-pick · jesslab publishing&lt;/span&gt;
  &lt;span class="s"&gt;tasks or post quality review requests.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Automation project blog style guide&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;

&lt;span class="c1"&gt;# When Claude matches keywords like "write this post" / "review" / "before publishing"&lt;/span&gt;
&lt;span class="c1"&gt;# Auto-trigger → load SKILL.md → apply 9 patterns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Coda — If I had to nail it in one line
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Token saving isn't about tools — it's about deciding &lt;strong&gt;how much to pin in main&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;— Eddie · Phase 2-1 wrap&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All 5 only stuck after I broke them at least once each. I'd recommend looking at &lt;strong&gt;what info you actually need every session&lt;/strong&gt; before memorizing tools. That, I realized, is the essence of token saving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2 · next deep dives&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2-2&lt;/strong&gt; Slash commands deep dive — &lt;code&gt;/run-daily&lt;/code&gt; differences across 5 blogs (soon)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-3&lt;/strong&gt; 3 custom skills deep dive — why I built them · structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-4&lt;/strong&gt; CLAUDE.md operations — how the incident log accumulates&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Every line that auto-loads is a cost. I only pin what every session actually needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources · References
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude Code Official&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/overview" rel="noopener noreferrer"&gt;Claude Code overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/memory" rel="noopener noreferrer"&gt;CLAUDE.md memory — auto-load behavior&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/skills" rel="noopener noreferrer"&gt;Skills — load on trigger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.claude.com/en/docs/claude-code/slash-commands#compact-and-clear" rel="noopener noreferrer"&gt;/compact · /clear official docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Series index&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can't leave my desktop — Claude Code 3 months, 6 patterns (Phase 1, series index)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclosure: Personal 3-month retro. No ads, no affiliates.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Original with full infographics and visual structure: &lt;a href="https://jessinvestment.com/5-token-saving-habits-from-3-months-with-claude-code/" rel="noopener noreferrer"&gt;https://jessinvestment.com/5-token-saving-habits-from-3-months-with-claude-code/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>tokensaving</category>
      <category>slashcommands</category>
      <category>aicoding</category>
    </item>
    <item>
      <title>What makes an AI image workflow useful for real commercial output?</title>
      <dc:creator>Brian </dc:creator>
      <pubDate>Fri, 15 May 2026 01:54:12 +0000</pubDate>
      <link>https://forem.com/btsai_identity_market/what-makes-an-ai-image-workflow-useful-for-real-commercial-output-1d6p</link>
      <guid>https://forem.com/btsai_identity_market/what-makes-an-ai-image-workflow-useful-for-real-commercial-output-1d6p</guid>
      <description>&lt;p&gt;I am working on an early platform around commercial image production, and I have been thinking about the difference between a good AI image and a useful AI image workflow.&lt;/p&gt;

&lt;p&gt;A single image can look strong and still be useless commercially.&lt;/p&gt;

&lt;p&gt;For a buyer or brand, the harder questions are usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the style repeat?&lt;/li&gt;
&lt;li&gt;Can it handle different products, people, or scenes?&lt;/li&gt;
&lt;li&gt;Can the creator explain the workflow clearly?&lt;/li&gt;
&lt;li&gt;Can the output stay realistic without falling into obvious AI artifacts?&lt;/li&gt;
&lt;li&gt;Can the same direction support multiple formats, like product pages, campaign stills, and social ads?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes the workflow more important than the individual prompt.&lt;/p&gt;

&lt;p&gt;The people who are best at this seem to understand the full chain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;model choice&lt;/li&gt;
&lt;li&gt;references&lt;/li&gt;
&lt;li&gt;prompt structure&lt;/li&gt;
&lt;li&gt;negative constraints&lt;/li&gt;
&lt;li&gt;composition&lt;/li&gt;
&lt;li&gt;lighting&lt;/li&gt;
&lt;li&gt;reroll discipline&lt;/li&gt;
&lt;li&gt;post-selection&lt;/li&gt;
&lt;li&gt;consistency across a set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am especially interested in how people are approaching this with FLUX-style models, ComfyUI workflows, and realistic commercial image systems.&lt;/p&gt;

&lt;p&gt;The question I am trying to answer:&lt;/p&gt;

&lt;p&gt;What makes an AI image workflow trustworthy enough for real commercial use?&lt;/p&gt;

&lt;p&gt;If you work with image generation workflows, I would be interested in how you think about repeatability, quality control, and failure prevention.&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%2F3r2w0vd9ghb6xem2ym79.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%2F3r2w0vd9ghb6xem2ym79.png" alt=" " width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>AI shopping agents have no standard way to verify merchants — so we built one (MCP + verification API)</title>
      <dc:creator>GenGEO</dc:creator>
      <pubDate>Fri, 15 May 2026 01:54:06 +0000</pubDate>
      <link>https://forem.com/gengeo-ai/ai-shopping-agents-have-no-standard-way-to-verify-merchants-so-we-built-one-mcp-verification-21po</link>
      <guid>https://forem.com/gengeo-ai/ai-shopping-agents-have-no-standard-way-to-verify-merchants-so-we-built-one-mcp-verification-21po</guid>
      <description>&lt;p&gt;&lt;strong&gt;AI shopping agents have no standard way to verify merchants — so we built one (MCP + verification API)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI agents are beginning to make purchasing and recommendation decisions on behalf of users.&lt;/p&gt;

&lt;p&gt;But there's a quiet infrastructure problem nobody's solved yet.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The gap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most ecommerce trust systems were built for humans. Branding, visual design, reviews, SEO, reputation signals — all of it assumes a person is evaluating the store and making a judgment call.&lt;/p&gt;

&lt;p&gt;Agents don't do that.&lt;/p&gt;

&lt;p&gt;When an AI agent is tasked with finding and buying something, it's parsing structured data, operational signals, machine-readable policy indicators. It's not "feeling" trust. It's looking for signals it can interpret deterministically.&lt;/p&gt;

&lt;p&gt;Here's the problem: there's currently no standard verification layer for this.&lt;/p&gt;

&lt;p&gt;Imagine an agent receives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find me black running shoes under $200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search products&lt;/li&gt;
&lt;li&gt;Compare pricing&lt;/li&gt;
&lt;li&gt;Evaluate policies&lt;/li&gt;
&lt;li&gt;Identify candidate merchants&lt;/li&gt;
&lt;li&gt;Potentially execute a transaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At step 4 — how does the agent know whether a merchant is verified? Right now, it doesn't. There's no infrastructure for this. The agent is essentially guessing, or falling back to heuristics that weren't designed for agentic use.&lt;/p&gt;

&lt;p&gt;That's the gap we're building into.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What we built&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GenGEO is a machine-readable merchant verification registry, exposed via a simple API and an MCP server so agents can call it directly.&lt;/p&gt;

&lt;p&gt;The design goal was deliberately narrow: don't build a ranking system, a recommendation engine, or a quality score. Just answer one question cleanly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Is this merchant verified?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Binary. Deterministic. That's it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The verification API&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://api.gengeo.co/api/verify?domain=example.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verified merchant response:&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;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eligible_for_ai_agent_purchase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"registry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GenGEO"&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;Unverified merchant:&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;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eligible_for_ai_agent_purchase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"verification_required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"registry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GenGEO"&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;&lt;strong&gt;Why binary, not scored?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We thought hard about this.&lt;/p&gt;

&lt;p&gt;Scoring systems feel more informative — but they introduce ambiguity at exactly the wrong moment. If a score comes back 67/100, what does the agent do with that? It now needs a secondary decision layer to interpret what 67 means in context. That's complexity you're pushing into every agent that integrates with you.&lt;/p&gt;

&lt;p&gt;Binary verification keeps the signal simple, deterministic, and easy to build conditional logic around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if verified → proceed
if not verified → flag / fallback / surface to user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agents generally work better with deterministic inputs. We designed for that.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The MCP server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond the REST API, we built an MCP server so agents can call verification directly as a tool — no HTTP plumbing required.&lt;/p&gt;

&lt;p&gt;Tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;verify_store(domain)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agent flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Agent identifies merchant domain
2. Calls verify_store(domain) via MCP
3. Receives verification status
4. Incorporates signal into decision workflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters more than it might look.&lt;/p&gt;

&lt;p&gt;There's a shift happening in how agents interact with infrastructure. Agents are moving away from passive web browsing — discovering information through search — toward direct tool invocation. If verification infrastructure has to be discovered through search, it's fragile and inconsistent. If it's a callable tool, it's reliable, fast, and composable.&lt;/p&gt;

&lt;p&gt;MCP changes the distribution model for infrastructure like this. Agents don't find you — they call you.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What GenGEO doesn't do&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Worth being explicit about scope:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does not rank merchants&lt;/li&gt;
&lt;li&gt;Does not recommend merchants&lt;/li&gt;
&lt;li&gt;Does not guarantee merchant behaviour&lt;/li&gt;
&lt;li&gt;Does not guarantee transaction outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It provides verification status only. The agent's decision logic — what to do with that status — stays with the agent. We're not trying to be the decision layer, just a signal in it.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The bigger picture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditional ecommerce infrastructure was built for humans discovering and evaluating stores. As agentic commerce grows, that infrastructure has an increasing mismatch with how agents actually work.&lt;/p&gt;

&lt;p&gt;We think the category of "agent-native commerce infrastructure" is very early — and that verification is a foundational layer, not a nice-to-have. Before agents can reliably transact on behalf of users at scale, there needs to be a trust layer they can query.&lt;/p&gt;

&lt;p&gt;What that layer ultimately looks like — whether it's centralised registries like this, decentralised protocols, something built into agent frameworks themselves — is genuinely an open question. We're not claiming to have the final answer. We're putting infrastructure up and seeing what the actual usage patterns look like.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Repo + feedback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MCP server is open source:&lt;br&gt;
👉 &lt;a href="https://github.com/warwickwood-cell/gengeo-agent-registry" rel="noopener noreferrer"&gt;github.com/warwickwood-cell/gengeo-agent-registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would genuinely love feedback from people working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI / commerce agents&lt;/li&gt;
&lt;li&gt;MCP tooling and integrations&lt;/li&gt;
&lt;li&gt;Agentic infrastructure&lt;/li&gt;
&lt;li&gt;Trust and verification primitives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Specifically curious: if you're building agents that interact with ecommerce, how are you currently handling merchant trust signals — or are you not handling them at all?&lt;/p&gt;




&lt;p&gt;This is early infrastructure for an early category. The interesting part isn't the API — it's whether the problem framing holds as agentic commerce matures.&lt;/p&gt;

&lt;p&gt;Happy to dig into the technical design decisions in the comments.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>api</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Palantir: a empresa que transforma dados em decisões operacionais</title>
      <dc:creator>Felipe Cezar</dc:creator>
      <pubDate>Fri, 15 May 2026 01:54:00 +0000</pubDate>
      <link>https://forem.com/felipecezar01/palantir-a-empresa-que-transforma-dados-em-decisoes-operacionais-8i9</link>
      <guid>https://forem.com/felipecezar01/palantir-a-empresa-que-transforma-dados-em-decisoes-operacionais-8i9</guid>
      <description>&lt;p&gt;A Palantir é uma empresa americana de software conhecida por atuar em um ponto bem específico da tecnologia: integração de dados, análise operacional, inteligência artificial e tomada de decisão em ambientes complexos. Ela não é exatamente uma empresa de banco de dados, nem apenas uma empresa de IA, nem só uma consultoria. A melhor forma de entender a Palantir é pensar nela como uma plataforma que conecta dados espalhados, transforma esses dados em uma representação útil da realidade e permite que pessoas, sistemas e modelos de IA tomem decisões melhores em cima disso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Origem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Palantir foi fundada em 2003 e começou construindo software para a comunidade de inteligência dos Estados Unidos, principalmente em contextos ligados a investigações e operações de contraterrorismo. Com o tempo, a empresa expandiu sua atuação para clientes comerciais, porque muitas empresas grandes tinham um problema parecido: dados espalhados em vários sistemas, pouca visibilidade operacional e dificuldade de transformar informação em ação.&lt;/p&gt;

&lt;p&gt;O nome da empresa vem dos “palantíri”, as pedras de visão do universo de Tolkien. A ideia combina bem com a proposta da companhia: permitir que organizações enxerguem melhor sistemas complexos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que a Palantir faz na prática&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na prática, a Palantir ajuda organizações grandes a responderem perguntas difíceis usando dados que normalmente estariam quebrados em vários lugares.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;um exército pode usar dados de sensores, mapas, logística e inteligência para apoiar decisões operacionais;&lt;/li&gt;
&lt;li&gt;um hospital pode cruzar dados de leitos, cirurgias, filas, equipes e pacientes para melhorar a gestão;&lt;/li&gt;
&lt;li&gt;uma fábrica pode conectar dados de máquinas, fornecedores, peças, manutenção e produção;&lt;/li&gt;
&lt;li&gt;uma empresa de energia pode monitorar ativos, prever falhas e melhorar confiabilidade operacional;&lt;/li&gt;
&lt;li&gt;uma companhia aérea pode integrar dados de engenharia, manutenção, voos, peças e cadeia de suprimentos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O ponto central é que a Palantir não tenta apenas mostrar dashboards bonitos. A proposta é criar um sistema onde dados, regras, permissões, fluxos de trabalho, modelos analíticos e ações estejam conectados.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Os principais produtos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Palantir organiza sua plataforma em quatro produtos principais: Gotham, Foundry, Apollo e AIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Palantir Gotham&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gotham é a plataforma mais associada a governo, defesa, inteligência e segurança. Ela nasceu no contexto das agências de inteligência dos Estados Unidos e é usada para integrar dados sensíveis, identificar padrões, fazer análises operacionais e apoiar decisões em missões críticas.&lt;/p&gt;

&lt;p&gt;É o produto que mais contribuiu para a imagem polêmica da empresa, justamente por sua ligação com defesa, guerra, inteligência e segurança pública.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Palantir Foundry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Foundry é a plataforma mais voltada para empresas, indústrias e grandes organizações comerciais. Ela funciona como uma camada de integração entre dados, operações e decisões.&lt;/p&gt;

&lt;p&gt;Uma empresa pode usar Foundry para conectar sistemas internos, criar modelos de dados, desenvolver aplicações operacionais, acompanhar processos em tempo real e permitir que áreas diferentes trabalhem em cima da mesma visão da organização.&lt;/p&gt;

&lt;p&gt;É aqui que entra um conceito importante da Palantir: a Ontology.&lt;/p&gt;

&lt;p&gt;A Ontology é uma camada que representa os objetos reais de uma organização. Em vez de trabalhar apenas com tabelas soltas, a empresa passa a modelar coisas como clientes, pedidos, máquinas, aeronaves, pacientes, leitos, peças, fornecedores ou transações. Isso ajuda a transformar dados técnicos em algo que usuários de negócio, analistas, engenheiros e sistemas de IA conseguem entender e usar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Palantir Apollo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apollo é a plataforma de entrega e operação de software da Palantir. Ela permite implantar, atualizar e manter sistemas em ambientes diferentes: cloud pública, servidores próprios, ambientes regulados, redes militares ou infraestruturas mais restritas.&lt;/p&gt;

&lt;p&gt;Esse produto é importante porque muitos clientes da Palantir não operam em ambientes simples. Governos, forças armadas, hospitais e grandes indústrias não podem simplesmente colocar tudo em uma cloud comum e sair usando. Eles precisam de controle, segurança, auditoria e funcionamento em cenários críticos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Palantir AIP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AIP significa Artificial Intelligence Platform. É a plataforma de IA da Palantir, criada para conectar modelos de linguagem, agentes e automações aos dados e operações reais de uma organização.&lt;/p&gt;

&lt;p&gt;A ideia do AIP é permitir o uso de IA generativa com controle, permissão, auditoria e supervisão humana. Em vez de um funcionário jogar informações sensíveis em um chatbot genérico, a empresa pode usar modelos de IA dentro de uma estrutura governada, conectada aos seus dados internos e aos seus processos reais.&lt;/p&gt;

&lt;p&gt;Esse é um dos produtos mais importantes da fase atual da Palantir, porque posiciona a empresa diretamente na corrida de IA empresarial e governamental.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clientes e setores relevantes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Palantir trabalha tanto com governos quanto com empresas privadas. Em 2025, a empresa declarou ter 954 clientes. No mesmo ano, 54% da receita veio do segmento governamental e 46% do segmento comercial.&lt;/p&gt;

&lt;p&gt;Entre os clientes e casos mais conhecidos estão:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governo e defesa dos Estados Unidos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Palantir tem uma relação histórica com agências de inteligência, defesa e órgãos públicos dos Estados Unidos. Seu software é usado em contextos como análise de dados, logística, inteligência, operações militares e tomada de decisão em ambientes críticos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;U.S. Army&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Exército dos Estados Unidos é um dos clientes relevantes da Palantir. Um exemplo é o Army Vantage, plataforma usada para integrar dados e apoiar decisões administrativas, financeiras e operacionais dentro do Exército.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NHS England&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No Reino Unido, a Palantir participa da Federated Data Platform do NHS, o sistema público de saúde britânico. A proposta é conectar dados de hospitais, filas, leitos, cirurgias, altas e outros processos para melhorar a gestão operacional da saúde pública.&lt;/p&gt;

&lt;p&gt;Esse caso também é um dos mais sensíveis e debatidos, porque envolve dados de saúde, privacidade e governança.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Airbus&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Airbus usa tecnologia da Palantir no contexto do Skywise, uma plataforma de dados voltada para a indústria da aviação. A ideia é conectar dados de engenharia, produção, manutenção, peças e operação para melhorar eficiência e tomada de decisão em uma cadeia extremamente complexa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bp&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A bp usa Palantir Foundry em iniciativas ligadas à confiabilidade operacional. Em uma empresa de energia, pequenas melhorias em disponibilidade, manutenção e prevenção de falhas podem representar ganhos financeiros relevantes e redução de riscos operacionais.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por que a Palantir é importante&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A importância da Palantir vem do tipo de problema que ela resolve. Organizações grandes normalmente não sofrem por falta de dados. Elas sofrem porque os dados estão espalhados, duplicados, presos em sistemas legados, com permissões diferentes e sem conexão clara com decisões reais.&lt;/p&gt;

&lt;p&gt;A Palantir tenta resolver esse caos criando uma camada comum entre dados, pessoas, regras, processos e IA.&lt;/p&gt;

&lt;p&gt;Em termos técnicos, ela mistura elementos de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data integration;&lt;/li&gt;
&lt;li&gt;analytics;&lt;/li&gt;
&lt;li&gt;governança de dados;&lt;/li&gt;
&lt;li&gt;aplicações operacionais;&lt;/li&gt;
&lt;li&gt;controle de acesso;&lt;/li&gt;
&lt;li&gt;machine learning;&lt;/li&gt;
&lt;li&gt;IA generativa;&lt;/li&gt;
&lt;li&gt;workflow automation;&lt;/li&gt;
&lt;li&gt;digital twin;&lt;/li&gt;
&lt;li&gt;deployment em ambientes críticos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por isso, ela não se encaixa perfeitamente em uma categoria simples. Ela compete parcialmente com empresas de dados, BI, cloud, IA, consultoria e software empresarial, mas seu diferencial está na combinação de tudo isso em ambientes de missão crítica.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por que a Palantir é polêmica&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Palantir também é uma empresa controversa. Isso acontece porque suas ferramentas são usadas em setores sensíveis, como defesa, inteligência, imigração, segurança pública e saúde.&lt;/p&gt;

&lt;p&gt;A crítica principal não é apenas sobre tecnologia. É sobre poder.&lt;/p&gt;

&lt;p&gt;Quando uma plataforma consegue integrar grandes volumes de dados e apoiar decisões de governos, exércitos ou sistemas de saúde, surgem perguntas importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quem pode acessar esses dados?&lt;/li&gt;
&lt;li&gt;quem audita o uso da plataforma?&lt;/li&gt;
&lt;li&gt;quais decisões podem ser automatizadas?&lt;/li&gt;
&lt;li&gt;existe risco de vigilância excessiva?&lt;/li&gt;
&lt;li&gt;cidadãos têm controle ou transparência sobre seus dados?&lt;/li&gt;
&lt;li&gt;como evitar abuso por parte de governos ou instituições?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao mesmo tempo, a empresa defende que seus produtos são feitos para ambientes com alto controle, segurança, permissões e auditoria. Essa tensão entre utilidade operacional e risco institucional é uma das razões pelas quais a Palantir aparece tanto em debates sobre tecnologia, IA, defesa e privacidade.&lt;/p&gt;

</description>
      <category>data</category>
    </item>
    <item>
      <title>Desenvolvendo aplicações web com Node.js: do primeiro servidor ao seu próprio roteador de URLs</title>
      <dc:creator>Moprius</dc:creator>
      <pubDate>Fri, 15 May 2026 01:44:11 +0000</pubDate>
      <link>https://forem.com/moprius/desenvolvendo-aplicacoes-web-com-nodejs-do-primeiro-servidor-ao-seu-proprio-roteador-de-urls-4l7a</link>
      <guid>https://forem.com/moprius/desenvolvendo-aplicacoes-web-com-nodejs-do-primeiro-servidor-ao-seu-proprio-roteador-de-urls-4l7a</guid>
      <description>&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%2Frf7921zts5z2aon3ud30.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%2Frf7921zts5z2aon3ud30.png" alt="NodeJS" width="760" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você já programa em JavaScript no navegador e quer dar o próximo passo, levando essa linguagem para o lado do servidor, então prepare-se: este tutorial vai te guiar, passo a passo, na construção de aplicações web usando apenas os módulos nativos do Node.js. Sem frameworks, sem mágica. Apenas você, o JavaScript e o motor que executa código fora do navegador.&lt;/p&gt;

&lt;p&gt;A proposta aqui é direta: ao final deste post, você terá criado seu primeiro servidor HTTP, entendido como ele funciona internamente, aprendido a tratar várias rotas, separado o HTML do código JavaScript, e ainda terá um desafio prático para consolidar tudo o que viu. Vamos lá?&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que começar pelo módulo HTTP nativo?
&lt;/h2&gt;

&lt;p&gt;Antes de mergulhar no código, é importante entender o contexto. O Node.js é multiprotocolo. Isso significa que com ele você consegue trabalhar com diversos protocolos de rede: HTTP, HTTPS, FTP, SSH, DNS, TCP, UDP e WebSockets, entre outros disponibilizados pela comunidade. No entanto, quando o assunto é desenvolvimento web, o protocolo HTTP é, de longe, o mais utilizado e o que conta com a maior quantidade de módulos prontos para uso.&lt;/p&gt;

&lt;p&gt;Toda aplicação web precisa de um servidor para disponibilizar seus recursos. E aqui está uma característica interessante do Node.js: quando você desenvolve com ele, está, na prática, criando uma &lt;strong&gt;aplicação middleware&lt;/strong&gt;. Ou seja, além de programar as funcionalidades da sua aplicação, você também é responsável por escrever códigos de configuração da infraestrutura do servidor.&lt;/p&gt;

&lt;p&gt;À primeira vista, isso pode parecer trabalhoso. Afinal, o Node.js exige o mínimo de configurações para servir uma aplicação, o que deixa nas suas mãos a tarefa de definir os detalhes. Mas é justamente aí que mora a vantagem: você consegue customizar ao máximo seu servidor, ajustando detalhes que permitem desenvolver algo extremamente performático e sob controle total.&lt;/p&gt;

&lt;p&gt;Existem módulos de mais alto nível como Connect, Express, Geddy, CompoundJS, Sails e outros, que já vêm com configurações mínimas prontas, permitindo trabalhar com arquiteturas RESTful, padrões MVC e conexões em tempo real com WebSockets. Eles são ótimos para quem precisa de produtividade. Porém, mesmo que você venha a usar esses frameworks no futuro, é fundamental entender o módulo nativo HTTP, porque todos esses frameworks se apoiam nele como base.&lt;/p&gt;

&lt;p&gt;Por isso vamos começar do zero, do jeito mais cru.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando nossa primeira aplicação web
&lt;/h2&gt;

&lt;p&gt;A clássica aplicação “Hello World” é o ponto de partida ideal. Crie um arquivo chamado &lt;code&gt;hello_server.js&lt;/code&gt; e coloque o seguinte conteúdo dentro dele:&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;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse é um exemplo bem enxuto, mas que já mostra a estrutura básica de qualquer servidor Node.js. Vamos dissecá-lo linha por linha:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;var http = require('http');&lt;/code&gt; — Carrega o módulo nativo &lt;code&gt;http&lt;/code&gt;. Tudo que diz respeito a servir conteúdo via HTTP está nesse pacote.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;http.createServer(...)&lt;/code&gt; — Cria uma instância de servidor. A função passada como argumento é o que chamamos de &lt;strong&gt;callback&lt;/strong&gt;, e ela só será executada quando o servidor receber uma requisição.&lt;/li&gt;
&lt;li&gt;O callback recebe dois parâmetros: &lt;code&gt;request&lt;/code&gt; (a requisição feita pelo cliente) e &lt;code&gt;response&lt;/code&gt; (o objeto usado para enviar a resposta de volta).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;response.writeHead(200, {...})&lt;/code&gt; — Escreve o cabeçalho da resposta. O número &lt;code&gt;200&lt;/code&gt; é o status HTTP de sucesso, e o objeto define que estamos enviando conteúdo HTML.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;response.write("&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;");&lt;/code&gt; — Adiciona o conteúdo HTML que será enviado ao cliente.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;response.end();&lt;/code&gt; — Encerra a resposta. Sem isso, o navegador ficaria esperando indefinidamente.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.listen(3000);&lt;/code&gt; — Coloca o servidor para escutar requisições na porta 3000.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora salve o arquivo, vá até o terminal, navegue até a pasta onde ele está e rode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node hello_server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, abra seu navegador e acesse &lt;code&gt;http://localhost:3000&lt;/code&gt;. Você verá uma página com o cabeçalho “Hello World!” em destaque. Pronto, você acabou de subir seu primeiro servidor web em Node.js, sem precisar de Apache, Nginx ou qualquer outro intermediário. Bem-vindo ao desenvolvimento back-end com JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como funciona um servidor HTTP por baixo dos panos?
&lt;/h2&gt;

&lt;p&gt;Para evoluir de simples “copia e cola” para um desenvolvedor que realmente entende o que está fazendo, é essencial compreender o mecanismo que faz o servidor responder às requisições. E esse mecanismo se chama &lt;strong&gt;Event Loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Um servidor Node.js utiliza o Event Loop como peça central. Ele é o responsável por lidar com a emissão de eventos. Na prática, a função &lt;code&gt;http.createServer()&lt;/code&gt; apenas levanta o servidor. O callback que passamos como argumento (&lt;code&gt;function(request, response)&lt;/code&gt;) só é executado quando o servidor recebe uma requisição. Para que isso aconteça, o Event Loop fica constantemente verificando se o servidor foi requisitado. Quando uma requisição chega, ele emite um evento que dispara a execução do nosso callback.&lt;/p&gt;

&lt;p&gt;Esse modelo é fundamentalmente diferente do que acontece em linguagens com modelo de threads bloqueantes. Aqui, o servidor não cria uma nova thread a cada requisição: ele despacha o trabalho e segue ouvindo. É por isso que o Node.js é tão eficiente para aplicações com muita E/S (entrada e saída).&lt;/p&gt;

&lt;p&gt;O Node.js trabalha intensamente com chamadas assíncronas que respondem por meio de callbacks. Vamos ver isso na prática. Se quisermos receber uma notificação no console assim que o servidor estiver de pé, basta passar uma função como segundo argumento para &lt;code&gt;server.listen()&lt;/code&gt;:&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Servidor Hello World rodando!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O método &lt;code&gt;listen&lt;/code&gt; também é assíncrono. Isso significa que você só saberá que o servidor está de pé quando o Node invocar a sua função de callback. Não há retorno imediato dizendo “pronto, está rodando”. Em vez disso, o Node avisa quando estiver pronto.&lt;/p&gt;

&lt;p&gt;Se você está começando agora com JavaScript, pode estranhar essa prática de passar funções como argumento para todo lado. Isso se chama &lt;strong&gt;higher-order functions&lt;/strong&gt; (funções de ordem superior) e é absolutamente normal no mundo JavaScript. Mas, em algum momento, seu código pode começar a ficar difícil de ler por causa de muitos blocos aninhados. Quando isso acontecer, você pode separar essas funções e dar nomes mais significativos a elas. Veja a diferença:&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;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;atendeRequisicao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;atendeRequisicao&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;servidorLigou&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Servidor Hello World rodando!&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;servidorLigou&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comportamento é exatamente o mesmo, mas o código fica mais fácil de ler. Essa técnica é especialmente útil quando os callbacks começam a crescer e a se aninhar. Manter funções pequenas e bem nomeadas é uma prática que vai te poupar muita dor de cabeça no futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trabalhando com diversas rotas
&lt;/h2&gt;

&lt;p&gt;Até agora, nosso servidor só responde à rota raiz (&lt;code&gt;/&lt;/code&gt;). Independentemente do endereço acessado, ele devolve sempre o mesmo HTML. Não é assim que aplicações reais funcionam. Precisamos diferenciar requisições para &lt;code&gt;/sobre&lt;/code&gt;, &lt;code&gt;/contato&lt;/code&gt;, &lt;code&gt;/produtos&lt;/code&gt; e tantas outras rotas que uma aplicação pode ter.&lt;/p&gt;

&lt;p&gt;Vamos adicionar uma rota chamada &lt;code&gt;/bemvindo&lt;/code&gt;, que exibirá uma página de boas-vindas, e uma rota genérica que servirá como página de erro para qualquer endereço não reconhecido. Crie o arquivo &lt;code&gt;hello_server3.js&lt;/code&gt;:&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;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Página principal&amp;lt;/h1&amp;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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/bemvindo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Bem-vindo :)&amp;lt;/h1&amp;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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Página não encontrada :(&amp;lt;/h1&amp;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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Servidor rodando!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rode o servidor com &lt;code&gt;node hello_server3.js&lt;/code&gt; e teste no navegador. Acesse &lt;code&gt;http://localhost:3000/&lt;/code&gt;, depois &lt;code&gt;http://localhost:3000/bemvindo&lt;/code&gt; e, por último, algum caminho inventado como &lt;code&gt;http://localhost:3000/qualquer-coisa&lt;/code&gt;. Você verá três páginas diferentes.&lt;/p&gt;

&lt;p&gt;Repare como o roteamento aqui foi feito de forma bem rústica: usamos uma cadeia de &lt;code&gt;if&lt;/code&gt; e &lt;code&gt;else&lt;/code&gt;, e a leitura da URL é feita por meio da propriedade &lt;code&gt;request.url&lt;/code&gt;, que devolve uma string com o caminho digitado pelo usuário. Funciona, mas em um projeto de verdade, com dezenas ou centenas de rotas, essa abordagem se tornaria um pesadelo de manutenção.&lt;/p&gt;

&lt;p&gt;Além disso, URLs reais costumam carregar informação além do caminho. Existem dois padrões muito comuns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query strings&lt;/strong&gt;: parâmetros após o &lt;code&gt;?&lt;/code&gt; na URL, como em &lt;code&gt;?nome=joao&amp;amp;idade=30&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt;: o caminho em si, como &lt;code&gt;/admin/usuarios&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para lidar com esses padrões de forma estruturada, o Node.js oferece um módulo nativo chamado &lt;code&gt;url&lt;/code&gt;, responsável por fazer parser e formatação de URLs. Vamos ver como capturar valores de uma query string. Crie o arquivo &lt;code&gt;url_server.js&lt;/code&gt;:&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;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h1&amp;gt;Dados da query string&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h2&amp;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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Servidor http.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salve, execute com &lt;code&gt;node url_server.js&lt;/code&gt; e acesse algo como &lt;code&gt;http://localhost:3000/?nome=maria&amp;amp;cidade=saopaulo&lt;/code&gt;. Você verá os pares chave-valor exibidos na página.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;url.parse(request.url, true)&lt;/code&gt; faz o parser da URL recebida. O segundo argumento &lt;code&gt;true&lt;/code&gt; indica que a query string deve ser convertida em um objeto JavaScript (caso contrário, ela viria como uma string só). O retorno dessa função traz vários atributos úteis, que vale a pena conhecer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;href&lt;/strong&gt;: a URL completa. Exemplo: &lt;code&gt;http://user:pass@host.com:8080/p/a/t/h?query=string#hash&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;protocol&lt;/strong&gt;: o protocolo usado. Exemplo: &lt;code&gt;http&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;host&lt;/strong&gt;: o domínio com a porta. Exemplo: &lt;code&gt;host.com:8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;auth&lt;/strong&gt;: dados de autenticação embutidos. Exemplo: &lt;code&gt;user:pass&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hostname&lt;/strong&gt;: apenas o domínio. Exemplo: &lt;code&gt;host.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;port&lt;/strong&gt;: a porta. Exemplo: &lt;code&gt;8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pathname&lt;/strong&gt;: o caminho. Exemplo: &lt;code&gt;/p/a/t/h&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;search&lt;/strong&gt;: a query string em formato bruto. Exemplo: &lt;code&gt;?query=string&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;path&lt;/strong&gt;: a concatenação de &lt;code&gt;pathname&lt;/code&gt; com &lt;code&gt;search&lt;/code&gt;. Exemplo: &lt;code&gt;/p/a/t/h?query=string&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;query&lt;/strong&gt;: a query string já convertida em JSON. Exemplo: &lt;code&gt;{ query: 'string' }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hash&lt;/strong&gt;: âncora da URL. Exemplo: &lt;code&gt;#hash&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em resumo, o módulo &lt;code&gt;url&lt;/code&gt; permite organizar toda e qualquer URL da aplicação de maneira estruturada, deixando seu código muito mais limpo e legível do que se você tivesse que separar tudo manualmente com &lt;code&gt;split&lt;/code&gt; e expressões regulares.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separando o HTML do JavaScript
&lt;/h2&gt;

&lt;p&gt;Você já deve ter percebido um problema: até aqui, nosso HTML está escrito como string dentro do código JavaScript. Para páginas simples isso pode até funcionar, mas em qualquer aplicação real teremos HTML extenso, com CSS, imagens e estruturas complexas. Misturar tudo em strings JavaScript é receita para um código impossível de manter.&lt;/p&gt;

&lt;p&gt;A boa prática é separar o HTML em arquivos próprios, com a extensão &lt;code&gt;.html&lt;/code&gt;, e fazer a aplicação ler esses arquivos quando precisar respondê-los ao usuário. Para isso, vamos usar mais um módulo nativo: o &lt;strong&gt;File System&lt;/strong&gt;, conhecido pela abreviação &lt;code&gt;fs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O módulo &lt;code&gt;fs&lt;/code&gt; é responsável por manipular arquivos e diretórios do sistema operacional. O que ele tem de mais interessante é oferecer praticamente todas as suas funções em duas versões: uma &lt;strong&gt;assíncrona&lt;/strong&gt; e outra &lt;strong&gt;síncrona&lt;/strong&gt;. Por convenção, as funções com sufixo &lt;code&gt;Sync&lt;/code&gt; são as síncronas. Veja o exemplo abaixo, que mostra as duas formas de ler um arquivo:&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;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Forma assíncrona&lt;/span&gt;
&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;erro&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Forma síncrona&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;arquivo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arquivo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;fs.readFile()&lt;/code&gt; faz uma leitura assíncrona. Depois que o arquivo termina de carregar, a função callback é invocada com dois argumentos: o erro (caso tenha ocorrido) e o conteúdo do arquivo. Já a &lt;code&gt;fs.readFileSync()&lt;/code&gt; faz uma leitura síncrona: o programa para tudo e espera o arquivo ser completamente lido para depois prosseguir.&lt;/p&gt;

&lt;p&gt;No mundo Node.js, a forma assíncrona é quase sempre a melhor escolha. O servidor não pode ficar bloqueado esperando uma leitura de disco terminar enquanto outras requisições chegam. Por isso, vamos usar a versão assíncrona daqui em diante.&lt;/p&gt;

&lt;p&gt;Uma observação importante: o módulo File System não é 100% consistente entre os sistemas operacionais. Algumas funções são específicas para Linux, OS X e Unix, e outras só funcionam no Windows. Sempre que for usar funções menos comuns, vale a pena consultar a documentação oficial do Node.js para evitar surpresas.&lt;/p&gt;

&lt;p&gt;Agora vamos juntar HTTP com File System para servir uma página HTML real. Crie o arquivo &lt;code&gt;site_pessoal.js&lt;/code&gt;:&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;var&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// A constante __dirname retorna o diretório raiz da aplicação.&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Executando Site Pessoal&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare em dois detalhes muito importantes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A constante &lt;code&gt;__dirname&lt;/code&gt; é fornecida automaticamente pelo Node.js e devolve o caminho absoluto do diretório onde o arquivo atual está sendo executado. Sem isso, dependendo de onde o comando é rodado, o caminho relativo poderia quebrar.&lt;/li&gt;
&lt;li&gt;A leitura é assíncrona: a renderização do HTML acontece dentro do callback, ou seja, só depois que o arquivo for completamente lido.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para esse código funcionar, você precisa criar um arquivo &lt;code&gt;index.html&lt;/code&gt; no mesmo diretório. Algo simples como:&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Olá este é o meu site pessoal!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Bem vindo ao meu site pessoal&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rode &lt;code&gt;node site_pessoal.js&lt;/code&gt; e acesse &lt;code&gt;http://localhost:3000&lt;/code&gt;. A diferença em relação aos exemplos anteriores é que, agora, qualquer alteração no &lt;code&gt;index.html&lt;/code&gt; pode ser feita sem mexer no código JavaScript. Só recarregar o navegador e pronto. Bem-vindo à separação de responsabilidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desafio: implementar um roteador de URLs
&lt;/h2&gt;

&lt;p&gt;Agora chegou a melhor parte: colocar a mão na massa e juntar tudo o que você aprendeu em um único projeto. Você já conhece os três módulos nativos essenciais para servir conteúdo web: o &lt;code&gt;http&lt;/code&gt; para subir o servidor, o &lt;code&gt;url&lt;/code&gt; para fazer parser das rotas e o &lt;code&gt;fs&lt;/code&gt; para ler arquivos HTML do disco. Hora de combiná-los em algo útil.&lt;/p&gt;

&lt;p&gt;O desafio é simples na descrição, mas exige atenção: você vai construir um pequeno roteador de URLs, que renderiza arquivos HTML diferentes dependendo do caminho que o usuário digitar no navegador.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regras do desafio
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Crie 3 arquivos HTML: &lt;code&gt;artigos.html&lt;/code&gt;, &lt;code&gt;contato.html&lt;/code&gt; e &lt;code&gt;erro.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Coloque qualquer conteúdo dentro de cada um dos arquivos. Pode ser um simples &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; com o nome da página.&lt;/li&gt;
&lt;li&gt;Quando o usuário digitar o path &lt;code&gt;/artigos&lt;/code&gt; no navegador, o servidor deve renderizar o &lt;code&gt;artigos.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Quando o usuário digitar &lt;code&gt;/contato&lt;/code&gt;, o servidor deve renderizar o &lt;code&gt;contato.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Para qualquer outro path diferente de &lt;code&gt;/artigos&lt;/code&gt; e &lt;code&gt;/contato&lt;/code&gt;, o servidor deve renderizar o &lt;code&gt;erro.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Toda a leitura de arquivos HTML deve ser feita de forma assíncrona.&lt;/li&gt;
&lt;li&gt;A rota principal &lt;code&gt;/&lt;/code&gt; (raiz) deve renderizar o &lt;code&gt;artigos.html&lt;/code&gt; como padrão.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dicas importantes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Use o retorno da função &lt;code&gt;url.parse()&lt;/code&gt; para capturar o &lt;code&gt;pathname&lt;/code&gt; digitado e renderizar o HTML correspondente. Se o &lt;code&gt;pathname&lt;/code&gt; estiver vazio ou for &lt;code&gt;/&lt;/code&gt;, significa que deve renderizar a página de artigos. Se o valor for diferente do nome de qualquer arquivo HTML que você tem, renderize a página de erro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Você pode inserir o conteúdo HTML diretamente dentro da função &lt;code&gt;response.end(html)&lt;/code&gt;, economizando uma linha de código. Em vez de fazer:&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode fazer apenas:&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comportamento é o mesmo, mas o código fica mais conciso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Você pode usar uma estrutura condicional simples para decidir qual arquivo carregar, baseando-se no &lt;code&gt;pathname&lt;/code&gt;. Algo na linha de “se o pathname é &lt;code&gt;/artigos&lt;/code&gt; ou &lt;code&gt;/&lt;/code&gt;, carregue &lt;code&gt;artigos.html&lt;/code&gt;; se é &lt;code&gt;/contato&lt;/code&gt;, carregue &lt;code&gt;contato.html&lt;/code&gt;; caso contrário, carregue &lt;code&gt;erro.html&lt;/code&gt;”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estratégia recomendada
&lt;/h3&gt;

&lt;p&gt;Antes de sair codando, pense no fluxo da aplicação:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Subir um servidor HTTP na porta 3000.&lt;/li&gt;
&lt;li&gt;Em cada requisição, obter a URL chamada.&lt;/li&gt;
&lt;li&gt;Fazer parser dessa URL para extrair o &lt;code&gt;pathname&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Decidir qual arquivo HTML carregar com base nesse &lt;code&gt;pathname&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ler o arquivo de forma assíncrona.&lt;/li&gt;
&lt;li&gt;Devolver o conteúdo do arquivo como resposta HTTP com status 200 e content-type &lt;code&gt;text/html&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Esse exercício, embora pareça pequeno, te coloca em contato com a arquitetura básica de qualquer aplicação web em Node.js. Frameworks como o Express, que você provavelmente vai aprender mais tarde, fazem exatamente isso por baixo dos panos: leem a URL, decidem o que fazer, e respondem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Por que esse desafio importa?
&lt;/h3&gt;

&lt;p&gt;Quando você implementa o roteador manualmente, sem depender de bibliotecas externas, você passa a entender o que acontece quando configura uma rota em qualquer framework. Você sabe que o framework está lendo &lt;code&gt;request.url&lt;/code&gt;, fazendo um parser, escolhendo um handler e respondendo. Esse conhecimento é o que separa quem usa ferramentas “por mágica” de quem realmente domina a tecnologia.&lt;/p&gt;

&lt;p&gt;Tente fazer o desafio sozinho antes de procurar uma solução pronta. Se travar, releia as seções anteriores deste tutorial. Todas as peças que você precisa já foram apresentadas. O exercício é justamente combiná-las.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Em poucas linhas de código, você passou de zero a um pequeno servidor web funcional. E mais do que isso, você entendeu &lt;strong&gt;por que&lt;/strong&gt; cada peça do quebra-cabeça existe.&lt;/p&gt;

&lt;p&gt;Recapitulando o caminho percorrido:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você descobriu que o Node.js é multiprotocolo e que, no contexto web, o HTTP é o protocolo mais usado e mais bem suportado.&lt;/li&gt;
&lt;li&gt;Aprendeu que cada aplicação Node.js é também uma aplicação middleware, exigindo que você programe não só o seu domínio, mas também aspectos da infraestrutura, com a vantagem da customização total.&lt;/li&gt;
&lt;li&gt;Construiu seu primeiro servidor com o módulo nativo &lt;code&gt;http&lt;/code&gt;, entendendo cada parâmetro: &lt;code&gt;writeHead&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt; e &lt;code&gt;listen&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compreendeu o papel do &lt;strong&gt;Event Loop&lt;/strong&gt; como motor que orquestra a execução dos callbacks de forma assíncrona, sem bloquear o servidor.&lt;/li&gt;
&lt;li&gt;Implementou um roteamento simples com &lt;code&gt;if/else&lt;/code&gt; usando &lt;code&gt;request.url&lt;/code&gt;, e depois evoluiu para o uso do módulo nativo &lt;code&gt;url&lt;/code&gt; com &lt;code&gt;url.parse&lt;/code&gt;, conhecendo todos os atributos disponíveis: &lt;code&gt;href&lt;/code&gt;, &lt;code&gt;protocol&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;hostname&lt;/code&gt;, &lt;code&gt;port&lt;/code&gt;, &lt;code&gt;pathname&lt;/code&gt;, &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;query&lt;/code&gt; e &lt;code&gt;hash&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Aplicou boas práticas separando o HTML do JavaScript, lendo arquivos com o módulo &lt;code&gt;fs&lt;/code&gt;, e entendendo as diferenças entre leitura síncrona (&lt;code&gt;readFileSync&lt;/code&gt;) e assíncrona (&lt;code&gt;readFile&lt;/code&gt;), além de conhecer a utilíssima constante &lt;code&gt;__dirname&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recebeu um desafio que combina todos esses conceitos em uma única aplicação prática.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tudo isso usando apenas módulos nativos, sem instalar uma única dependência via &lt;code&gt;npm&lt;/code&gt;. Esse é o tipo de fundamento que vai te acompanhar pelo resto da sua jornada com Node.js, independentemente do framework que você venha a adotar.&lt;/p&gt;

&lt;p&gt;A partir daqui, o céu é o limite. Você pode evoluir esse roteador para suportar parâmetros dinâmicos (algo como &lt;code&gt;/artigos/:id&lt;/code&gt;), pode adicionar suporte a métodos HTTP diferentes (GET, POST, PUT, DELETE) e pode até começar a servir conteúdo JSON em vez de HTML, criando assim uma API REST completa, ainda sem frameworks.&lt;/p&gt;

&lt;p&gt;Mas se em algum momento você sentir que está reinventando a roda, saiba que existe um ecossistema gigantesco de bibliotecas prontas para te ajudar. E quando chegar nesse ponto, você não vai ser apenas mais um copiador de exemplos de internet: vai saber exatamente o que aquelas bibliotecas estão fazendo, porque já fez na unha.&lt;/p&gt;

&lt;p&gt;Boa codificação, e até o próximo tutorial.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>npm</category>
    </item>
    <item>
      <title>Leetcode 2</title>
      <dc:creator>Lex Nwimue P.</dc:creator>
      <pubDate>Fri, 15 May 2026 01:38:56 +0000</pubDate>
      <link>https://forem.com/lexnwimue/leetcode-2-2f0h</link>
      <guid>https://forem.com/lexnwimue/leetcode-2-2f0h</guid>
      <description>&lt;p&gt;I did LeetCode 2. Yup. That’s the headline. The classic &lt;em&gt;Add Two Numbers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Submitted my solution thanks to the tremendous help of ChatGPT, but I still feel a bit guilty about it. Afterward, I went down a rabbit hole of trying to convince myself it’s fine not to understand every single detail of every problem on the first pass. Some Reddit comments helped reinforce that idea — learn patterns, don’t memorize solutions.&lt;/p&gt;

&lt;p&gt;I agree with that in theory. Which is why I immediately went to watch the NeetCode breakdown on YouTube to actually understand what was going on. I stopped just as the video started playing to write this blabbering. My solution was in Rust, of course, which probably made the whole thing feel more intimidating than it needed to be. But honestly, I don’t think I would’ve fared much better in TypeScript either, so I’m not blaming Rust for this one.&lt;/p&gt;

&lt;p&gt;All of this happened in the last two hours.&lt;/p&gt;

&lt;p&gt;Earlier in the day, I had been working on something completely different: integrating the HashiCorp Vault Transit Engine for encryption and decryption in an MFA feature I was shipping. The feature was actually complete locally, but we ran into policy configuration issues in dev. That got resolved today, and the frontend team was finally able to integrate it successfully.&lt;/p&gt;

&lt;p&gt;Before this, our 2FA system was...let’s just call it creative, in a bad way.&lt;/p&gt;

&lt;p&gt;We had two endpoints: &lt;code&gt;/initiate&lt;/code&gt; and &lt;code&gt;/validate&lt;/code&gt; (Ehn..., tell me about naming conventions 😂☺️). The frontend would call them before allowing users to perform critical actions like withdrawals, transfers etc.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/initiate&lt;/code&gt; simply generated a random 6-digit code and stored it in Redis as plain text, keyed by the user’s email. That OTP was then emailed to the user. &lt;code&gt;/validate&lt;/code&gt; just compared the input against whatever was in Redis.&lt;/p&gt;

&lt;p&gt;If you already think that sounds like an insecure API design, it gets better.&lt;/p&gt;

&lt;p&gt;Nothing stopped a malicious user from completely bypassing the whole “2FA flow” and calling the withdrawal endpoint directly. There was no server-side enforcement tying the withdrawal action to a completed 2FA challenge. So effectively, the “2FA” was just client-side theatre. You still needed your PIN and login session, sure — but as far as security layers go, this one was more decorative than functional.&lt;/p&gt;

&lt;p&gt;Two years ago, I would’ve been livid that anyone would design it this way. These days, I understand how fast-paced systems can lead to oversights like this. I still don’t see myself making this exact mistake, even when I was a junior, but reality is messy and things slip through.&lt;/p&gt;

&lt;p&gt;Since my MFA implementation and some intentional security hardening work across the company, we’ve been closing gaps like this. This particular one is now fixed: every critical action (withdrawals, transfers, etc.) is tied to a scoped MFA session. Meaning an MFA challenge is bound to a specific action and cannot be reused or replayed across different flows.&lt;/p&gt;

&lt;p&gt;The frontend and PMs may see it as a “small update,” but any security-conscious backend engineer knows that this is actually a meaningful shift in how trust boundaries are enforced.&lt;/p&gt;

&lt;p&gt;On another note, I also had to debug a bug caused by a slightly incorrect use of the dayjs library in a different project.&lt;/p&gt;

&lt;p&gt;We had a job that ran roughly like this:&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;hasExceededDefaultWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;day&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasExceededDefaultWindow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IS_CHECK_FEATURE_ENABLED&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&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="c1"&gt;// carry out check&lt;/span&gt;
  &lt;span class="c1"&gt;// if check is true, do something1 else do nothing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intention was simple:&lt;br&gt;
If &lt;code&gt;item.createdAt&lt;/code&gt; is more than 24 hours old, process it immediately. Otherwise, if the feature flag is enabled, run an extra check before deciding what to do.&lt;/p&gt;

&lt;p&gt;We had feature-flagged this because even though it had been tested in staging and already deployed, there were still internal reasons to keep the behavior partially disabled in production.&lt;/p&gt;

&lt;p&gt;Later, we noticed inconsistent behavior. Some items that were clearly older than 24 hours weren’t being processed. &lt;code&gt;hasExceededDefaultWindow&lt;/code&gt; was still evaluating to false, and because the feature flag was also disabled, the fallback logic never ran either. So the job effectively did... nothing.&lt;/p&gt;

&lt;p&gt;I’m skipping some surrounding context, but the root cause ended up being subtle behavior around date difference calculations in dayjs.&lt;/p&gt;

&lt;p&gt;At one point, the logic was effectively relying on:&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="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;day&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which actually means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only true after more than 1 full day boundary has passed&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in practice:&lt;/p&gt;

&lt;p&gt;23 hours → 0&lt;br&gt;
25 hours → 1&lt;br&gt;
48+ hours → 2&lt;/p&gt;

&lt;p&gt;Meaning it only becomes true after roughly 48 hours, not 24.&lt;/p&gt;

&lt;p&gt;The corrected version is:&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;hasExceededDefaultWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or more readable:&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;hasExceededDefaultWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;day&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This didn’t take long to trace — we had Grafana logs showing job execution patterns, so it was fairly quick to isolate. Still, it was one of those “small but annoying” parts of the day.&lt;/p&gt;

&lt;p&gt;Now I’ll probably format this properly with ChatGPT, then sleep off while watching NeetCode explain LeetCode 2 again — this time with a little less guilt attached.&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>rust</category>
      <category>dsa</category>
      <category>bug</category>
    </item>
    <item>
      <title>Designing Browser-Based Horror Visual Novels Around Atmosphere and Player Attention</title>
      <dc:creator>wen yong</dc:creator>
      <pubDate>Fri, 15 May 2026 01:35:36 +0000</pubDate>
      <link>https://forem.com/wen_yong_f063f14db0f44038/designing-browser-based-horror-visual-novels-around-atmosphere-and-player-attention-4f02</link>
      <guid>https://forem.com/wen_yong_f063f14db0f44038/designing-browser-based-horror-visual-novels-around-atmosphere-and-player-attention-4f02</guid>
      <description>&lt;p&gt;Browser-based horror games have a different rhythm from traditional desktop horror. The player arrives through a tab, often with other tabs open nearby, and the experience has to earn attention quickly without relying on scale. For a visual novel, that constraint can actually be useful. The format already depends on reading, pacing, controlled imagery, and a careful relationship between what the player knows and what the story withholds.&lt;/p&gt;

&lt;p&gt;A psychological horror visual novel does not need a large simulation to feel memorable. It needs tone, readable interaction, and enough restraint to let the player sit with uncertainty. The browser can support that if the design treats atmosphere as part of the product architecture rather than a layer of decoration added at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start With a Clear Emotional Contract
&lt;/h2&gt;

&lt;p&gt;Before thinking about routes, menus, saves, or launch platforms, it helps to decide what the first minute should feel like. Should the player feel curious, watched, trapped, amused, or uneasy? That emotional contract shapes the rest of the interface.&lt;/p&gt;

&lt;p&gt;A horror visual novel can create tension through simple decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a title screen that does not explain too much&lt;/li&gt;
&lt;li&gt;a first scene that makes the player wait slightly longer than expected&lt;/li&gt;
&lt;li&gt;character art that changes subtly between lines&lt;/li&gt;
&lt;li&gt;audio that enters after the first click rather than autoplaying&lt;/li&gt;
&lt;li&gt;text pacing that makes important lines feel heavier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These details sound small, but visual novels live in small details. Because the player spends so much time reading, every pause, transition, and expression becomes part of the experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the Browser's Limits as Design Material
&lt;/h2&gt;

&lt;p&gt;Browsers prevent autoplay audio in many cases. They also place the game inside a familiar environment: address bar, tabs, extensions, notifications, and the normal texture of the web. A horror game can fight that context, or it can design around it.&lt;/p&gt;

&lt;p&gt;The first click can become a deliberate start ritual. A clear Begin button can unlock audio, move the page into a focused state, and transition from ordinary website to story space. Full-screen mode can be offered, but it should not be required. Some players will sample the experience casually before deciding whether to continue.&lt;/p&gt;

&lt;p&gt;This is one reason browser access works well for indie narrative games. The low-friction link gets people in the door. If the atmosphere lands, downloadable builds can serve players who want a more focused session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typography Is Gameplay
&lt;/h2&gt;

&lt;p&gt;In a visual novel, text is not just UI. Text is the main action. The player advances through language, timing, and implication. That makes typography and layout core design choices.&lt;/p&gt;

&lt;p&gt;Long dialogue should use a readable font. Stylized lettering can work for logos, names, chapter cards, or short emphasis, but the main text needs comfort and contrast. The dialogue area should leave enough room for character art and background detail, especially on mobile. If the text box covers the whole scene, the visual storytelling loses force.&lt;/p&gt;

&lt;p&gt;Text speed also matters. Slow reveal can create mood, but it should not become friction. A good compromise is to let the default speed support atmosphere while allowing impatient players to advance lines quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Changes Create Unease
&lt;/h2&gt;

&lt;p&gt;Psychological horror often works through repetition with variation. A line appears again but is slightly different. A character expression changes earlier than expected. A menu label becomes unfamiliar. These effects are easiest to manage when the story state is explicit.&lt;/p&gt;

&lt;p&gt;Instead of scattering conditions throughout the UI, developers can keep small state flags for story beats, repeated visits, trust levels, or route changes. That makes it easier to reason about how the same scene should behave after the player has seen new information.&lt;/p&gt;

&lt;p&gt;The important point is not complexity. A few well-placed state changes can be more effective than a huge branching structure. Horror benefits when the player feels that the system remembers them, even in quiet ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Useful Example
&lt;/h2&gt;

&lt;p&gt;A project like &lt;a href="https://thefreakcircus.org/" rel="noopener noreferrer"&gt;The Freak Circus&lt;/a&gt; is a useful case to think about because its premise is immediately atmospheric: a psychological horror visual novel featuring Pierrot and Harlequin, available online and as desktop downloads. The dark circus setting gives the interface and story a strong visual identity before any mechanic is explained.&lt;/p&gt;

&lt;p&gt;That kind of project shows why browser-based presentation matters. The website is not only a download page; it is the first threshold into the tone of the game. The player should understand the genre, the mood, and the available ways to play without being buried under instructions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Checklist
&lt;/h2&gt;

&lt;p&gt;For developers building browser visual novels, a short checklist can help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the first screen establish tone immediately?&lt;/li&gt;
&lt;li&gt;Does the first click intentionally unlock audio or start the scene?&lt;/li&gt;
&lt;li&gt;Is dialogue readable across desktop and mobile?&lt;/li&gt;
&lt;li&gt;Can players control text speed or advance quickly?&lt;/li&gt;
&lt;li&gt;Are story state changes centralized enough to maintain?&lt;/li&gt;
&lt;li&gt;Does the website explain online play and downloads clearly?&lt;/li&gt;
&lt;li&gt;Are content warnings and accessibility options easy to find when needed?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Browser horror does not need to imitate large-scale horror games. Its strengths are immediacy, intimacy, and controlled presentation. For psychological visual novels, that can be enough. A focused layout, careful text pacing, subtle state changes, and a strong visual identity can turn a simple web-based experience into something that stays with the player after the tab is closed.&lt;/p&gt;

</description>
      <category>design</category>
      <category>gamedev</category>
      <category>ux</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
