<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Neo Tang</title>
    <description>The latest articles on DEV Community by Neo Tang (@tangweikun).</description>
    <link>https://dev.to/tangweikun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F873577%2F3e2c6f20-25b2-4ca1-a080-f09f5d6418a3.png</url>
      <title>DEV Community: Neo Tang</title>
      <link>https://dev.to/tangweikun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tangweikun"/>
    <language>en</language>
    <item>
      <title>Uwarp: 500+ Free Browser UI Tools (No Signup)</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Sat, 26 Sep 2026 13:08:32 +0000</pubDate>
      <link>https://dev.to/tangweikun/uwarp-500-free-browser-ui-tools-no-signup-1b6h</link>
      <guid>https://dev.to/tangweikun/uwarp-500-free-browser-ui-tools-no-signup-1b6h</guid>
      <description>&lt;p&gt;Default design tools often mean installers, accounts, or uploading files to someone else’s server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.uwarp.design" rel="noopener noreferrer"&gt;Uwarp&lt;/a&gt; is a free collection of &lt;strong&gt;500+ browser UI tools&lt;/strong&gt;—image and audio conversion, SVG, color, icons, mockups, and a few training games—meant to run locally in your tab. No signup for the tools themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can do
&lt;/h2&gt;

&lt;p&gt;A few examples from the homepage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Colour Contrast Checker&lt;/strong&gt; — live WCAG ratio for foreground / background pairs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tints and Shades&lt;/strong&gt; — build scales from any hex, export HEX / RGB / CSS / JSON&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free SVG Icons&lt;/strong&gt; — search Material Icons, Font Awesome, Heroicons, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image to Pixel Art&lt;/strong&gt; — convert photos with grid size and palettes, download PNG&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MP3 Cover Adder&lt;/strong&gt; — embed album art and edit ID3 tags in the browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GIF to Live Photo&lt;/strong&gt; — turn GIFs into Live Photo–ready &lt;code&gt;.mov&lt;/code&gt; without uploading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also lighter “recall” games (color, shape, sound) if you want a break that still trains visual / audio memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for makers, too
&lt;/h2&gt;

&lt;p&gt;If you ship a product, &lt;a href="https://www.uwarp.design/submit" rel="noopener noreferrer"&gt;submit a curated listing&lt;/a&gt; for manual review. Approved tools can show up as link-out pages under &lt;code&gt;/curated&lt;/code&gt;. Free curated submission is open; paid featured placement is not for sale yet.&lt;/p&gt;

&lt;p&gt;There’s also a separate hardware check playground at &lt;a href="https://hardware-test.uwarp.design/" rel="noopener noreferrer"&gt;hardware-test.uwarp.design&lt;/a&gt; if you need quick browser device detection.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Site: &lt;a href="https://www.uwarp.design" rel="noopener noreferrer"&gt;https://www.uwarp.design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Submit a product: &lt;a href="https://www.uwarp.design/submit" rel="noopener noreferrer"&gt;https://www.uwarp.design/submit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a tool saves you five minutes, share it with a teammate—or star related open-source bits when you find them. Feedback welcome.&lt;/p&gt;

</description>
      <category>design</category>
      <category>css</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>SVG Cursors You Can Actually Ship: Introducing `@sherotree/cursors`</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Sat, 26 Sep 2026 12:04:04 +0000</pubDate>
      <link>https://dev.to/tangweikun/svg-cursors-you-can-actually-ship-introducing-sherotreecursors-7oc</link>
      <guid>https://dev.to/tangweikun/svg-cursors-you-can-actually-ship-introducing-sherotreecursors-7oc</guid>
      <description>&lt;p&gt;Default OS cursors are fine. For a product UI, they often feel generic.&lt;/p&gt;

&lt;p&gt;I extracted the SVG hotspot cursors we use on &lt;a href="https://www.uwarp.design" rel="noopener noreferrer"&gt;Uwarp&lt;/a&gt; into a tiny MIT package: &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/@sherotree/cursors" rel="noopener noreferrer"&gt;&lt;code&gt;@sherotree/cursors&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F79gyj4czqllhoctidxwn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F79gyj4czqllhoctidxwn.gif" alt="@sherotree/cursors demo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s included
&lt;/h2&gt;

&lt;p&gt;Four cursors with correct hotspot offsets baked into CSS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;default&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pointer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grab&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;grabbing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus slightly smaller variants under a &lt;code&gt;1280px&lt;/code&gt; viewport width.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&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; @sherotree/cursors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Global usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@sherotree/cursors/style.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Next.js App Router, import once from &lt;code&gt;app/layout.tsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That sets &lt;code&gt;body&lt;/code&gt; cursors, remaps common interactive selectors (&lt;code&gt;a:hover&lt;/code&gt;, &lt;code&gt;button:hover&lt;/code&gt;, &lt;code&gt;[role=button]&lt;/code&gt;, …), and overrides Tailwind’s &lt;code&gt;.cursor-default&lt;/code&gt; / &lt;code&gt;.cursor-pointer&lt;/code&gt; / &lt;code&gt;.cursor-grab&lt;/code&gt; / &lt;code&gt;.cursor-grabbing&lt;/code&gt; so those utilities keep the custom look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoped usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@sherotree/cursors/scoped.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sherotree-cursors"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- custom cursors only inside here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@sherotree/cursors" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@sherotree/cursors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sherotree/cursors" rel="noopener noreferrer"&gt;https://github.com/sherotree/cursors&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it, a star or issue on the repo helps a lot. Happy shipping.&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>svg</category>
    </item>
    <item>
      <title>Jev Isn't a Chatbot — It's a System One Model for Typed Decisions</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Mon, 21 Sep 2026 15:56:54 +0000</pubDate>
      <link>https://dev.to/tangweikun/jev-isnt-a-chatbot-its-a-system-one-model-for-typed-decisions-5fmi</link>
      <guid>https://dev.to/tangweikun/jev-isnt-a-chatbot-its-a-system-one-model-for-typed-decisions-5fmi</guid>
      <description>&lt;p&gt;If you've built agents in 2025–2026, you already know the awkward middle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hand-written &lt;code&gt;if&lt;/code&gt; rules are too brittle for fuzzy judgments ("is this urgent?", "which team?", "is this tool call safe?").&lt;/li&gt;
&lt;li&gt;A frontier LLM can answer those questions — but it's slow, expensive, and returns &lt;em&gt;prose&lt;/em&gt; you still have to parse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Jev&lt;/strong&gt; (from TypeSafe AI) is aimed squarely at that gap. It doesn't write essays. It reads your program's state and returns &lt;strong&gt;typed, calibrated decisions&lt;/strong&gt; your code can branch on immediately.&lt;/p&gt;

&lt;p&gt;This post is a practical intro for indie / SaaS builders who want the mental model, a first API call, and a few real patterns — not a press release.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Jev actually is
&lt;/h2&gt;

&lt;p&gt;TypeSafe calls Jev a &lt;strong&gt;System One&lt;/strong&gt; model.&lt;/p&gt;

&lt;p&gt;Think Kahneman: System Two is slow, verbal reasoning (what chat LLMs imitate). System One is the fast gut check. Jev is built for the &lt;em&gt;software&lt;/em&gt; version of that gut check — routing, scoring, filtering, gating — at high volume.&lt;/p&gt;

&lt;p&gt;You send:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;state&lt;/code&gt;&lt;/strong&gt; — the context (ticket text, JSON event, agent messages, …)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;questions&lt;/code&gt;&lt;/strong&gt; — one or more typed questions about that state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You get back structured answers with probabilities. No free-text. No "sorry, as an AI…" preamble.&lt;/p&gt;

&lt;p&gt;Training focus is &lt;strong&gt;RLCD&lt;/strong&gt; (&lt;em&gt;Reinforcement Learning for Calibrated Decisions&lt;/em&gt;): when Jev says ~80% confidence, the goal is that it's right about ~80% of the time. That calibration is what makes thresholds usable in production instead of vibes-based prompt engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three question types (that's the whole surface)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;What you ask&lt;/th&gt;
&lt;th&gt;What you get back&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;choice&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pick 1 of up to 255 labelled options&lt;/td&gt;
&lt;td&gt;Winning key + per-option probabilities + confidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;score&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Place input on an ordered 2–10 level scale&lt;/td&gt;
&lt;td&gt;Fractional score + distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;noul&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes/no as a probability&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;noul&lt;/code&gt; in &lt;code&gt;[0, 1]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can ask &lt;strong&gt;several questions in one request&lt;/strong&gt;. They evaluate in parallel and share the state cost — so batching beats a loop of tiny calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tiny example: urgency gate
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.typesafe.ai/v1/systemone &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TYPESAFE_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "jev-latest",
    "state": "Hi, I'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;'ve been trying to connect Stripe for 3 days and it keeps failing. I'&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;'m losing sales. Please help ASAP.",
    "questions": {
      "is_urgent": {
        "type": "noul",
        "instructions": "The message conveys urgency or time-sensitivity"
      }
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A typical answer looks like:&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;"is_urgent"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"noul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noul"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.999&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;Then your code stays boring (in a good way):&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_urgent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;noul&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ticket&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;No regex. No JSON-schema-from-an-LLM-that-sometimes-breaks. The type is fixed by the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for agents (not just classifiers)
&lt;/h2&gt;

&lt;p&gt;Agents spend most of their loop on &lt;em&gt;tiny&lt;/em&gt; judgments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this still needed?&lt;/li&gt;
&lt;li&gt;Which model should handle this turn?&lt;/li&gt;
&lt;li&gt;Is this tool call too risky?&lt;/li&gt;
&lt;li&gt;Which queue should own this event?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those used to be either brittle rules or another LLM round-trip. Jev is the middle lane: &lt;strong&gt;fast enough for the hot path, structured enough for code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Public numbers TypeSafe / ecosystem write-ups commonly cite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency roughly &lt;strong&gt;70–500ms&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Far cheaper than frontier LLMs on comparable classification-style tasks (pricing differs between direct TypeSafe access and hosted gateways — check the console you use)&lt;/li&gt;
&lt;li&gt;Output tokens free on the decision API shape (you pay for input / state)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use an LLM for generation and open-ended reasoning. Use Jev for the decisions &lt;em&gt;around&lt;/em&gt; that generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Patterns that actually ship
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Ticket / email triage
&lt;/h3&gt;

&lt;p&gt;One &lt;code&gt;state&lt;/code&gt;, multiple questions: route (choice), urgency (noul), lead quality (score). Auto-handle high-confidence cases; escalate the uncertain band.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Model routing
&lt;/h3&gt;

&lt;p&gt;Ask Jev which tier should run this turn ("fast lookup" vs "architecture / high-stakes"). LangChain's experimental &lt;code&gt;ModelRouterMiddleware&lt;/code&gt; is built around this idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tool-call guardrails ("auto mode")
&lt;/h3&gt;

&lt;p&gt;Before &lt;code&gt;bash&lt;/code&gt; / delete / payment tools execute, ask a noul: "is this risky / irreversible?" Block or confirm when probability is high. Same pattern coding harnesses already use — now available as a cheap, open classifier layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Indie product glue
&lt;/h3&gt;

&lt;p&gt;If you run SEO tools, support inboxes, or agent workflows (hello, build-in-public SaaS), Jev is a good fit anywhere you currently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompt an LLM just to get a label, or&lt;/li&gt;
&lt;li&gt;maintain a growing pile of keyword heuristics&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  LangChain sketch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_typesafe&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Noul&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TypeSafeClassifier&lt;/span&gt;

&lt;span class="n"&gt;classifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TypeSafeClassifier&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;state&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;The deploy failed twice and customers are seeing 500s. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Can someone look now?&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;questions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;urgent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Noul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Does this need attention right now?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;urgency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nouls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;urgent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;noul&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State can be text, structured data, or LangChain messages — handy inside middleware / nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ecosystem tips (beyond the core API)
&lt;/h2&gt;

&lt;p&gt;The community moved fast after launch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;awesome-jev / jev-mcp&lt;/strong&gt; style tooling around MCP clients&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jevlang&lt;/strong&gt; — Python "smart if" syntax for decision workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jev-router&lt;/strong&gt; — route Claude Code / Codex turns to cheaper vs stronger models&lt;/li&gt;
&lt;li&gt;browser / automation pilots that treat Jev as the &lt;em&gt;chooser&lt;/em&gt;, not the writer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're exploring for a weekend project, start with one noul gate in an existing script. Don't rebuild your whole agent day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical gotchas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pin model versions in production&lt;/strong&gt; (&lt;code&gt;jev-1.x.x&lt;/code&gt;) if thresholds matter — &lt;code&gt;jev-latest&lt;/code&gt; can shift.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch questions&lt;/strong&gt; on shared state instead of N sequential calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use confidence / probability bands&lt;/strong&gt;: auto-approve high certainty, human or LLM escalate the middle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jev is not a chat UX.&lt;/strong&gt; Don't put it in front of end users as a conversational product. Put it &lt;em&gt;inside&lt;/em&gt; the product.&lt;/li&gt;
&lt;li&gt;Access paths vary (TypeSafe waitlist / console, gateways like OpenRouter / Vercel AI Gateway, or hosted metered keys). Pick one and keep the key server-side only.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Who's behind it (short)
&lt;/h2&gt;

&lt;p&gt;TypeSafe AI was founded by Diogo Almeida (ex-OpenAI, co-inventor work around RLHF), with Erik Gafni and Sasha Sheng. The company came out of stealth in September 2026. The thesis is blunt: if AI is going to change work, &lt;strong&gt;people can't be the only consumers of intelligence&lt;/strong&gt; — most of it should live quietly in software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;Jev won't write your README. It will decide, in under half a second, whether this ticket is urgent, which team owns it, and whether your agent should be allowed to run that delete.&lt;/p&gt;

&lt;p&gt;For indie builders drowning in "tiny LLM calls that only return a label," that might be the most useful new primitive of the season.&lt;/p&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What is Jev: &lt;a href="https://www.jevtypesafeai.com/what-is-jev" rel="noopener noreferrer"&gt;https://www.jevtypesafeai.com/what-is-jev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to use / API: &lt;a href="https://www.jevtypesafeai.com/how-to-use" rel="noopener noreferrer"&gt;https://www.jevtypesafeai.com/how-to-use&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LangChain write-up: &lt;a href="https://www.langchain.com/blog/building-a-harness-with-jev" rel="noopener noreferrer"&gt;https://www.langchain.com/blog/building-a-harness-with-jev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;If you ship something with Jev (routing, triage, guardrails), drop a comment — always hungry for real indie use cases.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
    </item>
    <item>
      <title>Build UChart with KendoReact</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Sun, 23 Mar 2025 03:09:12 +0000</pubDate>
      <link>https://dev.to/tangweikun/build-uchart-with-kendoreact-4ldd</link>
      <guid>https://dev.to/tangweikun/build-uchart-with-kendoreact-4ldd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kendoreact"&gt;KendoReact Free Components Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UChart&lt;/strong&gt;&lt;br&gt;
Provides out-of-the-box chart templates and supports custom chart styles to help you quickly generate beautiful charts&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;Link: &lt;a href="https://kendo.uwarp.design/" rel="noopener noreferrer"&gt;https://kendo.uwarp.design/&lt;/a&gt;&lt;br&gt;
Repo:&lt;a href="https://github.com/tangweikun/kendo" rel="noopener noreferrer"&gt;https://github.com/tangweikun/kendo&lt;/a&gt;&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%2Fhlhedd7wyqivgbkdltsb.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%2Fhlhedd7wyqivgbkdltsb.png" alt="Image description" width="800" height="887"&gt;&lt;/a&gt;&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%2Fv5yc3r9fio7lo0xzs3ke.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%2Fv5yc3r9fio7lo0xzs3ke.png" alt="Image description" width="800" height="873"&gt;&lt;/a&gt;&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%2Fg73o7mks0y948rrmlifw.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%2Fg73o7mks0y948rrmlifw.png" alt="Image description" width="800" height="883"&gt;&lt;/a&gt;&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%2Fuhbi9d3rl4cgnbo26i1a.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%2Fuhbi9d3rl4cgnbo26i1a.png" alt="Image description" width="800" height="894"&gt;&lt;/a&gt;&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%2Fcc2e79txfpwcbmjdydli.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%2Fcc2e79txfpwcbmjdydli.png" alt="Image description" width="800" height="889"&gt;&lt;/a&gt;&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%2F1ed2jgsxfyzvhjrf11qa.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%2F1ed2jgsxfyzvhjrf11qa.png" alt="Image description" width="800" height="878"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  KendoReact Experience
&lt;/h2&gt;

&lt;p&gt;I use the Checkbox,Splitter,TabStrip,TabStripTab,Button,NumericTextBox,Notification,NotificationGroup,Fade,Dialog,Label,Slider,Switch on the Uchart, help me quickly build the UI part. KendoReact is very easy to get started with, It took me almost no time to use it in my projects.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>kendoreactchallenge</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🏆 Pick Your Champion - Netlify Dynamic Site Challenge</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Sun, 12 May 2024 06:25:06 +0000</pubDate>
      <link>https://dev.to/tangweikun/pick-your-champion-netlify-dynamic-site-challenge-502k</link>
      <guid>https://dev.to/tangweikun/pick-your-champion-netlify-dynamic-site-challenge-502k</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/netlify"&gt;Netlify Dynamic Site Challenge&lt;/a&gt;: Visual Feast &amp;amp; Build with Blobs &amp;amp; Clever Caching.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://uwarp.netlify.app/pick-your-champion"&gt;Pick Your Champion&lt;/a&gt;&lt;/strong&gt; is an interactive Quiz, player can pick the ideal type here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🚀 &lt;a href="https://uwarp.netlify.app/pick-your-champion"&gt;Pick Your Champion&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📸 Screenshots&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9cwk8ddphe80udylr5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9cwk8ddphe80udylr5r.png" alt="Image description" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgvml9gbr4u1fppggjme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgvml9gbr4u1fppggjme.png" alt="Image description" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4l00ror8gtmrucxpoil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4l00ror8gtmrucxpoil.png" alt="Image description" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fobtfwfxhcjne67cb7dhh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fobtfwfxhcjne67cb7dhh.png" alt="Image description" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Primitives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.netlify.com/image-cdn/overview/"&gt;Netlify Image CDN&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Integrated Netlify Image CDN to dynamically manipulate images at the time of delivery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilized parameterized transformation by adjusting parameters like width, height, quality, format, fit, and position in the image URL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.netlify.com/blobs/overview/"&gt;Netlify Blobs&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Use it to store voting data.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@netlify/blobs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gameId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gameId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roleId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;roleId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`pick-your-champion`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gameId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;roleId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;roleId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;preCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gameId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;lastModified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&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="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;&lt;strong&gt;&lt;a href="https://docs.netlify.com/platform/caching/"&gt;Netlify's fine-grained cache control capabilities&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implement custom Cache-Control headers, utilize the Netlify-CDN-Cache-Control header for edge caching, and demonstrate cache invalidation using cache tags.&lt;/p&gt;

&lt;p&gt;First fetching timing cost&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzgdnekps1o0lusxyfbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzgdnekps1o0lusxyfbr.png" alt="Image description" width="579" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fetching from the cache&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t9gn3su23mr4mlipg0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t9gn3su23mr4mlipg0e.png" alt="Image description" width="575" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Response Headers&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejlji0e2e9355e8qqat3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejlji0e2e9355e8qqat3.png" alt="Image description" width="535" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Netlify's cache control capabilities is so good, make the API 10 times faster from the cache!!!&lt;/p&gt;

</description>
      <category>netlifychallenge</category>
      <category>devchallenge</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🎨 Logo Hunter - Netlify Dynamic Site Challenge</title>
      <dc:creator>Neo Tang</dc:creator>
      <pubDate>Sun, 12 May 2024 03:55:18 +0000</pubDate>
      <link>https://dev.to/tangweikun/logo-hunter-netlify-dynamic-site-challenge-367g</link>
      <guid>https://dev.to/tangweikun/logo-hunter-netlify-dynamic-site-challenge-367g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/netlify"&gt;Netlify Dynamic Site Challenge&lt;/a&gt;: Visual Feast.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://uwarp.netlify.app/logo-hunter"&gt;Logo Hunter&lt;/a&gt;&lt;/strong&gt; boasts a user-friendly interface that allows visitors to effortlessly find app logos from the App Store. At the same time, it was also released to the Figma plug-in community, designers can click the logo to place it in a Figma file.&lt;br&gt;
The project utilizes Netlify's image CDN to fetch and optimize images dynamically. By applying resizing and format optimization, the project creates visually appealing galleries based on user input. This implementation guarantees efficient image delivery and a smooth user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🚀 &lt;a href="https://uwarp.netlify.app/logo-hunter"&gt;Logo Hunter&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎨 &lt;a href="https://www.figma.com/community/plugin/1365349580836615037/logo-hunter-for-apple-store"&gt;Logo Hunter in Figma&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Find any app logo from the App Store by searching with keywords and filtering by country.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transform the logo by adjusting parameters such as width, height, quality, format, fit, and position in the image URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have the convenience of either downloading or copying the logo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insert the logo to the Figma file&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📸 Screenshots&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc7qyzcw4t6yike9iibq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc7qyzcw4t6yike9iibq.png" alt="homescreen" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frexxdn8w7vhk84qjmgpu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frexxdn8w7vhk84qjmgpu.png" alt="screenshot" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4tuc6cag6uwgq6yy6xe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4tuc6cag6uwgq6yy6xe.png" alt="screenshot" width="361" height="627"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Primitives
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Netlify Image CDN&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrated Netlify Image CDN to dynamically manipulate images at the time of delivery.&lt;/li&gt;
&lt;li&gt;Utilized parameterized transformation by adjusting parameters like width, height, quality, format, fit, and position in the image URL.
&lt;/li&gt;
&lt;/ul&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://uwarp.netlify.app/.netlify/images?url=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nx"&gt;artworkUrl512&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="s2"&gt;`&amp;amp;fit=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;w=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;h=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;fm=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;position=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>netlifychallenge</category>
      <category>devchallenge</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
