<?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: Adrian</title>
    <description>The latest articles on DEV Community by Adrian (@elvingts).</description>
    <link>https://dev.to/elvingts</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%2F4114157%2F39809338-f0c3-4189-b8f5-de604e2e7466.png</url>
      <title>DEV Community: Adrian</title>
      <link>https://dev.to/elvingts</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elvingts"/>
    <language>en</language>
    <item>
      <title>From Zero to 3 Merged PRs: Contributing Python CLI Recipes to BasedHardware/omi</title>
      <dc:creator>Adrian</dc:creator>
      <pubDate>Wed, 23 Sep 2026 07:39:54 +0000</pubDate>
      <link>https://dev.to/elvingts/from-zero-to-3-merged-prs-contributing-python-cli-recipes-to-basedhardwareomi-50lp</link>
      <guid>https://dev.to/elvingts/from-zero-to-3-merged-prs-contributing-python-cli-recipes-to-basedhardwareomi-50lp</guid>
      <description>&lt;p&gt;Over the past few weeks, I’ve been contributing to &lt;strong&gt;BasedHardware/omi&lt;/strong&gt;, the open-source AI wearable project. As of this week, all three of my pull requests have been officially approved and merged into &lt;code&gt;main&lt;/code&gt; by core maintainers and Omi's founder Nik Shevchenko (&lt;code&gt;@kodjima33&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Here is a quick recap of the journey, the recipes built, and 3 key engineering lessons learned along the way.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 What We Built: The Python CLI Recipe Trilogy
&lt;/h3&gt;

&lt;p&gt;The goal was to enable Omi users to seamlessly export and structure their conversational data without needing complex setups or external dependencies.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PR #13701: Conversations to Markdown&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built a lightweight CLI recipe to convert raw conversation JSON dumps into structured Markdown compatible with Obsidian, Notion, and local notes.&lt;/li&gt;
&lt;li&gt;Handled UTF-8 character encoding and atomic file writing to prevent corrupt exports.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PR #14458: Memories Export with Categorization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created an exporter for Omi's memory stream, organizing insights by date and category tags.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PR #13960: Action Items to Markdown with Full Unit Tests&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The most rigorous of the three! This recipe extracts action items and checklists into formatted task lists.&lt;/li&gt;
&lt;li&gt;When maintainer Aryan Gupta noted that earlier attempts had messy merge commits and no tests, I went back to the drawing board:

&lt;ul&gt;
&lt;li&gt;Implemented 9 comprehensive unit tests using Python’s standard &lt;code&gt;unittest&lt;/code&gt; (all 9 passed in 0.05s).&lt;/li&gt;
&lt;li&gt;Executed a clean linear git rebase on &lt;code&gt;origin/main&lt;/code&gt; to eliminate redundant commits.&lt;/li&gt;
&lt;li&gt;Result: Received quick approval from &lt;code&gt;@kodjima33&lt;/code&gt; and was merged directly into the core repo.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  💡 3 Key Lessons Learned
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Zero External Dependencies Win Every Time
&lt;/h4&gt;

&lt;p&gt;In open-source CLI tools, relying on third-party libraries introduces dependency bloat and breaking changes across user environments. Writing scripts purely with Python's standard library (&lt;code&gt;urllib.request&lt;/code&gt;, &lt;code&gt;json&lt;/code&gt;, &lt;code&gt;datetime&lt;/code&gt;, &lt;code&gt;argparse&lt;/code&gt;) guarantees that anyone can run the recipe out of the box with zero setup pain.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Welcome Tough Maintainer Feedback
&lt;/h4&gt;

&lt;p&gt;When a maintainer asks for tests or calls a branch dirty, don't get discouraged — treat it as free mentorship. Adding automated tests not only got the PR merged, but it also made the code unbreakable against future regressions.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Keep Git History Squeaky Clean
&lt;/h4&gt;

&lt;p&gt;Interactive rebasing and keeping commits atomic is a superpower. A clean, single-commit PR with passing CI makes a maintainer's job 10x easier to review and click "Merge".&lt;/p&gt;




&lt;h3&gt;
  
  
  🔮 What’s Next?
&lt;/h3&gt;

&lt;p&gt;I’m currently looking into extending these recipes to support direct third-party REST API payloads (like Todoist tasks and Notion blocks). &lt;/p&gt;

&lt;p&gt;Contributing to active AI hardware/software projects is one of the fastest ways to level up real-world software engineering skills. &lt;/p&gt;

&lt;p&gt;Have you contributed to open-source recently? What was your biggest takeaway from working with repository maintainers? Let's discuss below! 👇&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>devjournal</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Find, Fix, and Earn from Open Source Bug Bounties: A Developer's Guide</title>
      <dc:creator>Adrian</dc:creator>
      <pubDate>Wed, 09 Sep 2026 14:04:44 +0000</pubDate>
      <link>https://dev.to/elvingts/how-to-find-fix-and-earn-from-open-source-bug-bounties-a-developers-guide-574b</link>
      <guid>https://dev.to/elvingts/how-to-find-fix-and-earn-from-open-source-bug-bounties-a-developers-guide-574b</guid>
      <description>&lt;p&gt;Every developer wants to contribute to open source. But navigating issue trackers, submitting clean PRs, and getting your code merged can feel daunting — especially when real bug bounties or payouts are involved.&lt;/p&gt;

&lt;p&gt;Over the past few weeks, I've been active in open-source bug bounty hunting across repositories like &lt;strong&gt;Gyroflow&lt;/strong&gt;, &lt;strong&gt;Drizzle ORM&lt;/strong&gt;, &lt;strong&gt;EdgeChains&lt;/strong&gt;, and &lt;strong&gt;OphirPay&lt;/strong&gt;. Here is my exact workflow, technical setup, and lessons learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. 🔍 Finding High-Value &amp;amp; Low-Risk Issues
&lt;/h2&gt;

&lt;p&gt;Not all bounties or issues are created equal. When selecting issues to work on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check Escrow &amp;amp; Maintainer Trust:&lt;/strong&gt; Look for issues with verified escrow bots or active core maintainers who merge PRs consistently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze Competition:&lt;/strong&gt; Review existing open PRs. If 30+ PRs are already open for a single typo or simple fix, your time is better spent elsewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus on Core Value:&lt;/strong&gt; Look for well-defined technical issues — such as missing database schemas, edge-case parser fixes, or cross-platform metadata support.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. 🧪 Deep Technical Investigation Before Writing Code
&lt;/h2&gt;

&lt;p&gt;Before writing a single line of code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local Reproduction:&lt;/strong&gt; Write an isolated reproduction script or test runner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture Audit:&lt;/strong&gt; Understand how data flows through the upstream codebase (e.g., how result rows map in ORMs or how camera lens definitions are parsed).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check Test Suites:&lt;/strong&gt; Ensure you can run local unit tests clean before making modifications.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  3. 🤝 Collaboration Over Competition
&lt;/h2&gt;

&lt;p&gt;One of the biggest mistakes contributors make is fighting over single issues. On complex issues (like multi-part feature requests):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Propose Scope Splits:&lt;/strong&gt; Split back-end schema work from front-end UI selectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communicate Early in Comments:&lt;/strong&gt; Let maintainers and other contributors know what part of the issue you are taking on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag Core Maintainers:&lt;/strong&gt; Agree on clean scope divisions so everyone gets credit and payouts are distributed fairly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. 🛡️ PR Submission Checklist
&lt;/h2&gt;

&lt;p&gt;When opening your Pull Request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] Clear title referencing &lt;code&gt;Fixes #IssueNumber&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[x] Concise breakdown of changes made and tests run&lt;/li&gt;
&lt;li&gt;[x] Contributor License Agreement (CLA) signed&lt;/li&gt;
&lt;li&gt;[x] Zero merge conflicts with &lt;code&gt;main&lt;/code&gt; / &lt;code&gt;master&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Open-source bug bounty hunting isn't just about quick payouts — it's about building a verified public track record, learning real-world production codebases, and collaborating with global developers.&lt;/p&gt;

&lt;p&gt;What's your experience with open-source bounties or pull requests? Let's discuss in the comments below!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>bugbounty</category>
      <category>github</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Built 16 Developer Tools with Zero Backend and Full Privacy – and You Can Too</title>
      <dc:creator>Adrian</dc:creator>
      <pubDate>Tue, 08 Sep 2026 12:45:15 +0000</pubDate>
      <link>https://dev.to/elvingts/how-i-built-16-developer-tools-with-zero-backend-and-full-privacy-and-you-can-too-1bn</link>
      <guid>https://dev.to/elvingts/how-i-built-16-developer-tools-with-zero-backend-and-full-privacy-and-you-can-too-1bn</guid>
      <description>&lt;p&gt;Modern web development often overcomplicates simple utilities. Why spin up Node.js microservices, Postgres clusters, and Redis caches just to format JSON, test regular expressions, redact API keys, or calculate loan amortization?&lt;/p&gt;

&lt;p&gt;In this article, I want to share the exact architectural principles, client-side engineering practices, and lessons learned while building a suite of high-utility, privacy-first developer tools — hosted entirely as zero-backend static web applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Core Philosophy: Client-Side Sovereignty
&lt;/h2&gt;

&lt;p&gt;When developers paste internal configs, JWT tokens, customer payloads, or financial figures into online web tools, they take a privacy risk. Even well-intentioned platforms frequently log request payloads to telemetry, ingest data into LLM training corpuses, or leak secrets through CDN access logs.&lt;/p&gt;

&lt;p&gt;My premise was simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero Backend Required:&lt;/strong&gt; All data transformations occur 100% inside the user's browser sandbox using vanilla Web APIs and Web Workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline-Ready:&lt;/strong&gt; Once loaded, these tools function completely offline without internet access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant Latency:&lt;/strong&gt; No round-trip API delays. Processing happens at sub-millisecond local execution speeds.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. The Applications in Action
&lt;/h2&gt;

&lt;p&gt;Here is the live suite that embodies these principles:&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ 1. &lt;a href="https://omnitools-pro.surge.sh" rel="noopener noreferrer"&gt;OmniTools Pro&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A powerhouse client-side utility hub featuring 16 integrated developer tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON Formatter &amp;amp; Schema Validator:&lt;/strong&gt; Instant formatting, minify, sorting, and error inspection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT Decoder &amp;amp; Inspector:&lt;/strong&gt; Client-side token header/claims decoding without sending signatures over the wire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regex Tester &amp;amp; Sandbox:&lt;/strong&gt; Real-time regex pattern testing with capture groups and highlight overlays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base64, URL, Hash Generation:&lt;/strong&gt; Instant SHA-256, SHA-512, and HMAC processing using native browser WebCrypto API (&lt;code&gt;window.crypto.subtle&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown Live Preview:&lt;/strong&gt; Responsive split-pane live editor with instant AST compilation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://omnitools-pro.surge.sh" rel="noopener noreferrer"&gt;https://omnitools-pro.surge.sh&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 2. &lt;a href="https://aipromptlab-pro.surge.sh" rel="noopener noreferrer"&gt;AI PromptLab Pro&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;An intelligent prompt engineering laboratory for creators and engineers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client-side PII Masking:&lt;/strong&gt; Automatically detects and redacts emails, API keys, phone numbers, and names before prompts are copied into AI models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt Token Counter:&lt;/strong&gt; Accurate BPE token estimations directly in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variables &amp;amp; Template Engine:&lt;/strong&gt; Dynamic slot insertion for systematic prompt optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://aipromptlab-pro.surge.sh" rel="noopener noreferrer"&gt;https://aipromptlab-pro.surge.sh&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  📊 3. &lt;a href="https://fincalc-pro.surge.sh" rel="noopener noreferrer"&gt;FinCalc Pro&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;High-precision financial calculators running pure client-side math:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loan amortization with dynamic amortization tables and SVG charts.&lt;/li&gt;
&lt;li&gt;Investment growth projections with compound interest intervals.&lt;/li&gt;
&lt;li&gt;Fire/Retirement trajectory modelling with custom inflation vectors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://fincalc-pro.surge.sh" rel="noopener noreferrer"&gt;https://fincalc-pro.surge.sh&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🌐 4. &lt;a href="https://elvin-portfolio.surge.sh" rel="noopener noreferrer"&gt;Personal &amp;amp; Engineering Portfolio&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Showcasing the philosophy, benchmark metrics, and open-source contributions.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://elvin-portfolio.surge.sh" rel="noopener noreferrer"&gt;https://elvin-portfolio.surge.sh&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Key Architecture &amp;amp; Engineering Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A. Leverage Native Web APIs
&lt;/h3&gt;

&lt;p&gt;Instead of bloated npm dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebCrypto API (&lt;code&gt;crypto.subtle&lt;/code&gt;):&lt;/strong&gt; Delivers hardware-accelerated cryptographic hashes (SHA-256, HMAC) with zero dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Workers:&lt;/strong&gt; For large file processing (e.g. 10MB+ JSON datasets), offload parse routines to worker threads to keep the UI thread responsive at 60 FPS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canvas &amp;amp; SVG:&lt;/strong&gt; Lightweight data visualization without requiring heavy charting libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B. Deploying to Edge Without Servers
&lt;/h3&gt;

&lt;p&gt;Hosting is powered entirely by static edge distribution (Surge.sh / GitHub Pages / Cloudflare Pages). Deployment takes seconds, requires zero server maintenance, and costs $0 in database operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Support the Project &amp;amp; Source Code Access
&lt;/h2&gt;

&lt;p&gt;If you find these tools helpful or want to deploy your own customized developer toolkit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐️ Check out the live applications above.&lt;/li&gt;
&lt;li&gt;☕ &lt;strong&gt;Support the Project / Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://buymeacoffee.com/adriandev" rel="noopener noreferrer"&gt;Buy Me a Coffee&lt;/a&gt; | &lt;a href="https://paypal.me/adriandeveloper" rel="noopener noreferrer"&gt;PayPal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Source Code Packages &amp;amp; Commercial License:&lt;/strong&gt; Full modular source code available on our toolkit bundle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know in the comments: What is the single most important utility tool you use every day, and how do you protect sensitive data when using online tools?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Why parsing a 10MB JSON payload freezes your UI thread (and how to offload it to Web Workers)</title>
      <dc:creator>Adrian</dc:creator>
      <pubDate>Mon, 07 Sep 2026 14:51:10 +0000</pubDate>
      <link>https://dev.to/elvingts/why-parsing-a-10mb-json-payload-freezes-your-ui-thread-and-how-to-offload-it-to-web-workers-3e4k</link>
      <guid>https://dev.to/elvingts/why-parsing-a-10mb-json-payload-freezes-your-ui-thread-and-how-to-offload-it-to-web-workers-3e4k</guid>
      <description>&lt;p&gt;If you have ever built a dashboard or data analysis tool in JavaScript, you have probably run into this scenario: your app fetches a large JSON payload (say, 5MB to 20MB of raw records), runs &lt;code&gt;JSON.parse(data)&lt;/code&gt;, and for 300ms to 1.5 seconds, the entire browser tab completely freezes.&lt;/p&gt;

&lt;p&gt;Buttons don't click. CSS animations drop to 0 FPS. The browser might even throw an &lt;em&gt;"Unresponsive Script"&lt;/em&gt; warning.&lt;/p&gt;

&lt;p&gt;Here is why that happens, why most developers handle it wrong, and how to offload heavy JSON operations to native Web Workers with zero external libraries.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem: JavaScript is Single-Threaded
&lt;/h3&gt;

&lt;p&gt;The browser executes your JavaScript, layout calculations, and UI rendering on a &lt;strong&gt;single main thread&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you execute:&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;const&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&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;hugeRawString&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;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;active&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main thread cannot paint a single frame or respond to user inputs until &lt;code&gt;JSON.parse&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; have completely finished traversing the entire object graph.&lt;/p&gt;

&lt;p&gt;Even on modern M-series or high-end x86 CPUs, parsing a 15MB JSON file can take 400ms+. On mobile devices, it can easily take 2-4 seconds.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Bad Fix: &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;async/await&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A common misconception is that wrapping &lt;code&gt;JSON.parse&lt;/code&gt; in a &lt;code&gt;Promise&lt;/code&gt; or &lt;code&gt;setTimeout&lt;/code&gt; makes it non-blocking:&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="c1"&gt;// ❌ THIS STILL BLOCKS THE UI THREAD!&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parseDataAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&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;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&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="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&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;raw&lt;/span&gt;&lt;span class="p"&gt;));&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="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;While &lt;code&gt;setTimeout&lt;/code&gt; pushes the task to the next event loop tick, the moment that task executes, &lt;code&gt;JSON.parse&lt;/code&gt; &lt;strong&gt;still runs synchronously on the main thread&lt;/strong&gt;, locking the UI for the exact same amount of time.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Clean Solution: Inline Web Worker Dispatch
&lt;/h3&gt;

&lt;p&gt;Instead of adding a 50KB npm package, you can spawn an isolated Web Worker using a &lt;code&gt;Blob&lt;/code&gt; and &lt;code&gt;URL.createObjectURL&lt;/code&gt;. This runs in a separate OS thread without needing a separate hosted worker file:&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;function&lt;/span&gt; &lt;span class="nf"&gt;parseJsonInWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonString&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;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="nx"&gt;workerCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
      self.onmessage = function(e) {
        try {
          const parsed = JSON.parse(e.data);
          self.postMessage({ success: true, data: parsed });
        } catch (err) {
          self.postMessage({ success: false, error: err.message });
        }
      };
    `&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;blob&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;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;workerCode&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;application/javascript&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;workerUrl&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;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&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;worker&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;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workerUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;success&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;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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="nf"&gt;cleanup&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;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;resolve&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;reject&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;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;reject&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="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&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="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workerUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonString&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Benchmarks &amp;amp; Real-World Impact
&lt;/h3&gt;

&lt;p&gt;In our tests processing a 12.4 MB mock database export (approx 85,000 nested JSON objects):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Main Thread &lt;code&gt;JSON.parse&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Web Worker Pipeline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main Thread Lock Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;680 ms (UI Frozen)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0 ms (60 FPS Constant)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total Computation Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~710 ms&lt;/td&gt;
&lt;td&gt;~740 ms (incl. message clone)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User Experience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Page stutter / freeze&lt;/td&gt;
&lt;td&gt;Smooth progress spinner&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Although the total CPU time is slightly higher due to structured cloning across thread boundaries, the &lt;strong&gt;Main Thread stays completely responsive&lt;/strong&gt;. Input sliders, cancel buttons, and loading animations continue to render at 60 FPS.&lt;/p&gt;




&lt;h3&gt;
  
  
  Where to Use This Architecture
&lt;/h3&gt;

&lt;p&gt;This exact worker pattern is what powers the client-side JSON parser, YAML validator, and Diff engine inside &lt;a href="https://omnitools-pro.surge.sh" rel="noopener noreferrer"&gt;OmniTools Pro&lt;/a&gt;. Even when diffing two massive files, the UI never stutters because computation happens entirely in background threads.&lt;/p&gt;

&lt;p&gt;Have you tackled large JSON bottlenecks in your frontend apps? What's your go-to strategy? Let's discuss in the comments below!&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why your JSON and Regex tools shouldn't send data to a backend (and how I built a zero-leak client suite)</title>
      <dc:creator>Adrian</dc:creator>
      <pubDate>Mon, 07 Sep 2026 14:44:54 +0000</pubDate>
      <link>https://dev.to/elvingts/why-your-json-and-regex-tools-shouldnt-send-data-to-a-backend-and-how-i-built-a-zero-leak-client-c3a</link>
      <guid>https://dev.to/elvingts/why-your-json-and-regex-tools-shouldnt-send-data-to-a-backend-and-how-i-built-a-zero-leak-client-c3a</guid>
      <description>&lt;p&gt;Every developer does it at least once a week: you get an unformatted 2MB payload from an internal endpoint or a complex regex string from a colleague, and you throw it into an online web formatter or tester.&lt;/p&gt;

&lt;p&gt;The problem? Most top search results for "JSON formatter" or "JWT debugger" are laden with heavy ad trackers, telemetry pixels, and in several cases, quietly transmit the pasted text back to an external server. If that payload contains authorization headers, customer PII, API secrets, or internal database IDs, you have just unknowingly leaked confidential data.&lt;/p&gt;

&lt;p&gt;I got tired of worrying about this, so I built &lt;a href="https://omnitools-pro.surge.sh" rel="noopener noreferrer"&gt;&lt;strong&gt;OmniTools Pro&lt;/strong&gt;&lt;/a&gt; — a suite of 16 developer utilities that runs 100% inside your browser with zero backend data transmission.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works (and why the architecture matters)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero Server Footprint for Processing:&lt;/strong&gt;&lt;br&gt;
All operations—JSON parsing, YAML conversions, JWT decoding, UUID generation, Diff comparisons, and SHA/MD5 hashing—execute inside local Web Workers and standard Web APIs (&lt;code&gt;crypto.subtle&lt;/code&gt;, &lt;code&gt;JSON.parse&lt;/code&gt;). If you open your browser DevTools Network tab while using the tool, you will see zero outgoing POST requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Offline-First PWA:&lt;/strong&gt;&lt;br&gt;
The entire site is cached via a lightweight Service Worker. Once loaded once, you can turn off your Wi-Fi and format or diff code completely offline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sub-second Load Times:&lt;/strong&gt;&lt;br&gt;
Zero heavy frameworks, zero third-party tracking scripts. Pure vanilla HTML, modular JS, and clean CSS running on Global Edge CDN.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Live Demo &amp;amp; Feedback
&lt;/h3&gt;

&lt;p&gt;You can test it out live here: &lt;strong&gt;&lt;a href="https://omnitools-pro.surge.sh" rel="noopener noreferrer"&gt;https://omnitools-pro.surge.sh&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built this primarily to solve my own workflow friction, but I hope it saves other developers time and eliminates unnecessary privacy risks. If you run into edge cases or want additional offline utilities added, let me know in the comments!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>privacy</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
