<?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: Hemant Sharma</title>
    <description>The latest articles on DEV Community by Hemant Sharma (@hemant_s01).</description>
    <link>https://dev.to/hemant_s01</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%2F4239714%2F2b593f92-d3a1-4864-983a-0c0812befffa.png</url>
      <title>DEV Community: Hemant Sharma</title>
      <link>https://dev.to/hemant_s01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hemant_s01"/>
    <language>en</language>
    <item>
      <title>I built 61 dev tools without a framework — here's what I learned about HTML tokenization</title>
      <dc:creator>Hemant Sharma</dc:creator>
      <pubDate>Wed, 11 Nov 2026 18:52:21 +0000</pubDate>
      <link>https://dev.to/hemant_s01/i-built-61-dev-tools-without-a-framework-heres-what-i-learned-about-html-tokenization-1gol</link>
      <guid>https://dev.to/hemant_s01/i-built-61-dev-tools-without-a-framework-heres-what-i-learned-about-html-tokenization-1gol</guid>
      <description>&lt;p&gt;&lt;a href="//www.tools4market.online"&gt;&lt;/a&gt;&lt;br&gt;
The pitch is simple: tools4market.online is 61 browser-side dev tools — cron expression generator, JSON→CSV, HTML minifier, SVG optimizer, Markdown↔HTML, hash generator, text diff, email validator, robots.txt generator, and 50+ more. No login, no upload, no framework, no backend.&lt;/p&gt;

&lt;p&gt;The interesting part is what I had to build to stay dependency-free:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A hand-written HTML tokenizer (~190 lines)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The HTML5 spec says &lt;/p&gt;
 and &amp;lt;textarea&amp;gt; are RCDATA elements, but ONLY in the HTML namespace. Inside &amp;lt;svg&amp;gt;, they're normal elements. Get this wrong and a raw &amp;lt;title&amp;gt; inside an SVG silently swallows the rest of your page — which is exactly the bug I shipped and then spent a day finding.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The fix is a namespace context stack (html / svg / math). When you enter &amp;lt;svg&amp;gt;, push svg onto the stack; RCDATA/RAWTEXT rules apply only when the stack top is html. This is what the HTML5 spec calls "foreign content" handling.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;2. A multi-size favicon ICO encoder&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Modern browsers (everything since 2015) accept embedded PNG inside ICO files. So I skipped BMP encoding entirely — the ICO is a 6-byte header, N×16-byte ICONDIR entries, then concatenated PNG bytes per size. Tested by reading the archive back and comparing every CRC with node:zlib.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The PNGs themselves are rendered to canvas at 16/32/48/64/180/192/512, then toBlob'd. The ZIP is hand-encoded store-only (no DEFLATE) — favicons are tiny, no need for compression.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;3. A conservative SVG optimizer&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Strips comments, editor metadata (sodipodi/inkscape namespaces), unreferenced IDs, default attributes, collapses whitespace, shortens hex colors.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The non-obvious part: before removing an ID, you have to scan for references — url(#id), href="#id", xlink:href="#id", marker-start/mid/end, clip-path, mask, filter. AND scan &amp;lt;style&amp;gt; text content for ID selectors (path#myId { ... }). AND scan SMIL begin="myId.click" attributes. I initially shipped without the &amp;lt;style&amp;gt; scan and called it a "documented limitation" — then went back and did it properly.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;What I gave up staying dependency-free:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;JS minifier (deferred — needs Acorn or Terser, ~50KB, not worth the cost until traffic justifies it)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Full CommonMark (shipped a subset — tables, footnotes, GFM extensions all unsupported, documented on-page)&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;Any client-side analytics beyond GTM&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;A real test framework (using hand-rolled Node assertions)&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;The build:&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Single Node script (build.mjs) reads tool definitions from src/data/&amp;lt;em&amp;gt;.js, inlines scripts from src/runtime/&amp;lt;/em&amp;gt;.js, writes static HTML. Cloudflare Workers serves it. Desktop PageSpeed is 100/100/100/100 because there's nothing to slow it down — no framework hydration, no images on tool pages, no third-party JS.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;I'm shipping a new tool every few days. Looking for: what tool is missing from the set, what's broken in the ones I shipped, what tradeoffs you'd make differently.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Site: &amp;lt;a href="https://tools4market.online"&amp;gt;https://tools4market.online&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;


</description>
      <category>frontend</category>
      <category>html</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
