<?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: RK Riad Khan</title>
    <description>The latest articles on DEV Community by RK Riad Khan (@rkriad585).</description>
    <link>https://dev.to/rkriad585</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%2F4025303%2F912b9d91-54d5-4ac0-b025-7d0c07f9a62f.jpg</url>
      <title>DEV Community: RK Riad Khan</title>
      <link>https://dev.to/rkriad585</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rkriad585"/>
    <language>en</language>
    <item>
      <title>authority-auth: Stop Rolling Your Own Auth — A Framework-Agnostic Python Library</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Sun, 16 Aug 2026 16:11:07 +0000</pubDate>
      <link>https://dev.to/rkriad585/authority-auth-stop-rolling-your-own-auth-a-framework-agnostic-python-library-232b</link>
      <guid>https://dev.to/rkriad585/authority-auth-stop-rolling-your-own-auth-a-framework-agnostic-python-library-232b</guid>
      <description>&lt;p&gt;The problem&lt;/p&gt;

&lt;p&gt;Every Python web app eventually needs authentication, and every team ends up either gluing together half a dozen libraries or hand-rolling JWT logic. Both paths are full of security traps: weak token validation, no refresh-token rotation, missing lockouts, forgotten MFA.&lt;/p&gt;

&lt;p&gt;The library&lt;/p&gt;

&lt;p&gt;&lt;code&gt;authority-auth&lt;/code&gt; &lt;a href="https://github.com/rkriad585/authority" rel="noopener noreferrer"&gt;(https://github.com/rkriad585/authority)&lt;/a&gt; is a comprehensive, framework-agnostic Python authentication library. One core, written to be used from any stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;**JWT **access tokens with configurable expiry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refresh-token&lt;/strong&gt; rotation with family tracking and reuse detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TOTP MFA&lt;/strong&gt; with encrypted secrets and one-time recovery codes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebAuthn&lt;/strong&gt; passkeys for passwordless login&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RBAC&lt;/strong&gt; (roles/permissions) with a require_permission guard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API&lt;/strong&gt; keys, session management, and append-only audit logging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password security&lt;/strong&gt;: bcrypt hashing, complexity rules, history enforcement, and HIBP breach checking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Framework integrations&lt;/p&gt;

&lt;p&gt;It ships ready-made integrations for FastAPI, Flask, Django, and Starlette, plus framework-agnostic ASGI and WSGI middleware for anything else. Storage is pluggable, with SQLite (sync and async) included.&lt;/p&gt;

&lt;p&gt;Example apps you can actually run&lt;/p&gt;

&lt;p&gt;Since 0.2.5, every example app is a real web app — server-rendered HTML pages (login, register, dashboard) plus a JSON API, with an HttpOnly-cookie login flow. Run &lt;code&gt;python -m examples.apps.fastapi&lt;/code&gt;_app.app (or the Flask/Django/Starlette variants) and poke around.&lt;/p&gt;

&lt;p&gt;Get started&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;authority-auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs: rkriad585.github.io/authority (&lt;a href="https://rkriad585.github.io/authority/" rel="noopener noreferrer"&gt;https://rkriad585.github.io/authority/&lt;/a&gt;) · MIT licensed · Python 3.10+&lt;/p&gt;

</description>
      <category>authority</category>
      <category>webdev</category>
      <category>rkriad585</category>
      <category>python</category>
    </item>
    <item>
      <title>Just shipped TSkeleton 0.2.0 🦴</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Sun, 16 Aug 2026 06:05:52 +0000</pubDate>
      <link>https://dev.to/rkriad585/just-shipped-tskeleton-020-2g3o</link>
      <guid>https://dev.to/rkriad585/just-shipped-tskeleton-020-2g3o</guid>
      <description>&lt;p&gt;A zero-dependency library of 24 loading-skeleton Web Components — one tag per popular app: skeleton-facebook, skeleton-github, skeleton-tiktok, skeleton-youtube, skeleton-google and 19 more.&lt;/p&gt;

&lt;p&gt;Why I built it:&lt;br&gt;
• No Tailwind, no framework, no runtime deps — each skeleton is a self-contained custom element with its own shadow DOM&lt;br&gt;
• Built-in pulse and shimmer animations&lt;br&gt;
• Three levels of theming: global configure(), per-instance attributes, and deep CSS variables + ::part() hooks&lt;br&gt;
• Tree-shakable subpath imports, ES/CJS/UMD bundles, SSR-safe&lt;/p&gt;

&lt;p&gt;Try it from npm or a CDN. Docs and a live playground:&lt;br&gt;
&lt;a href="https://rkriad585.github.io/TSkeleton/" rel="noopener noreferrer"&gt;https://rkriad585.github.io/TSkeleton/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/rkriad585/TSkeleton" rel="noopener noreferrer"&gt;https://github.com/rkriad585/TSkeleton&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  webcomponents #typescript #frontend #opensource
&lt;/h1&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Announcing Abscom — Python-flavored C11</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Sun, 16 Aug 2026 02:31:00 +0000</pubDate>
      <link>https://dev.to/rkriad585/announcing-abscom-python-flavored-c11-474n</link>
      <guid>https://dev.to/rkriad585/announcing-abscom-python-flavored-c11-474n</guid>
      <description>&lt;p&gt;I've spent a while building &lt;strong&gt;Abscom&lt;/strong&gt;, a C11 library of reusable data structures with a Python-inspired dynamic runtime. It's now in review for the two big package registries: &lt;strong&gt;vcpkg&lt;/strong&gt; and &lt;strong&gt;ConanCenter&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%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3n94fntfn6qy8cyrfah7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3n94fntfn6qy8cyrfah7.png" alt="Home" width="800" height="450"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8c07lpj4547utlbwby7p.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8c07lpj4547utlbwby7p.png" alt="Examples" width="800" height="450"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmz47okgz0e6z06g955o5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmz47okgz0e6z06g955o5.png" alt="Abs" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Core data structures: dynamic arrays, strings, hashmaps, sets, matrices, data frames, CSV&lt;/li&gt;
&lt;li&gt;A dynamic runtime that makes C feel like Python: &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;None&lt;/code&gt;, &lt;code&gt;List()&lt;/code&gt;, &lt;code&gt;Dict()&lt;/code&gt;, &lt;code&gt;print&lt;/code&gt;, &lt;code&gt;foreach&lt;/code&gt;, &lt;code&gt;try/catch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Practical extras: regex, WebSockets, crypto, a small ML stack, image/plotting helpers&lt;/li&gt;
&lt;li&gt;Strict C11, no C++ required, zero deps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"abscom/abs.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;list_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&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;list_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&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="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sum = %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;   &lt;span class="c1"&gt;// sum = 42&lt;/span&gt;
    &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Packaging status:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;vcpkg&lt;/strong&gt; — port submitted: all 15 CI jobs (MSVC x86/x64/arm64, Linux, macOS, Android) are green&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;ConanCenter *&lt;/em&gt;— recipe submitted and building
Try it: &lt;a href="https://github.com/rkriad585/Abscom" rel="noopener noreferrer"&gt;github.com/rkriad585/Abscom&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>c</category>
      <category>rkriad585</category>
      <category>abscom</category>
    </item>
    <item>
      <title>Cowser: A Fun ASCII-Art Animal CLI in Pure Python</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:50:44 +0000</pubDate>
      <link>https://dev.to/rkriad585/cowser-a-fun-ascii-art-animal-cli-in-pure-python-1m1k</link>
      <guid>https://dev.to/rkriad585/cowser-a-fun-ascii-art-animal-cli-in-pure-python-1m1k</guid>
      <description>&lt;p&gt;If you miss the good old days of cowsay, you'll love Cowser - a modern,&lt;br&gt;
cross-platform reimagining written in Python with zero runtime dependencies.&lt;/p&gt;

&lt;p&gt;What does it do?&lt;br&gt;
Cowser wraps your message in a speech (or thought!) bubble and prints it&lt;br&gt;
above a randomly chosen animal. Greet a friend, pipe in some text, or just&lt;br&gt;
ask for a fortune.&lt;/p&gt;

&lt;p&gt;Features&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;35 built-in animals across 12 categories: cows, cats, pets, birds, sea
life, farm, wild, robot, hedgehog, alien, spooky, and mythical creatures&lt;/li&gt;
&lt;li&gt;cowsay-style moods: --mode dead, borg, greedy, paranoid, stoned, wired...&lt;/li&gt;
&lt;li&gt;Thought bubbles with --think&lt;/li&gt;
&lt;li&gt;Custom eyes and tongues via --eyes and --tongue&lt;/li&gt;
&lt;li&gt;Word wrapping (-W), disabled with -n&lt;/li&gt;
&lt;li&gt;Rainbow, bold, and 17 ANSI colors&lt;/li&gt;
&lt;li&gt;--fortune for a random fortune&lt;/li&gt;
&lt;li&gt;Render two animals side by side with --and&lt;/li&gt;
&lt;li&gt;An interactive REPL session with --interactive&lt;/li&gt;
&lt;li&gt;--seed for reproducible output&lt;/li&gt;
&lt;li&gt;Art packs: drop .cow, .txt, or .art files in a folder and they load
automatically (classic cowsay cowfiles supported)&lt;/li&gt;
&lt;li&gt;Config file at ~/.config/neostore/cowser/config.toml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quick start&lt;br&gt;
    pip install cowser&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cowser Alice                     # greet with a random animal
cowser --cow owl Bob             # pick a specific animal
echo "From stdin" | cowser       # pipe a message
cowser --fortune                 # random fortune
cowser --rainbow --bold --message "Party time!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Also a library&lt;br&gt;
cowser is a pure, type-hinted function you can embed in your own tools:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from cowser import render, render_pair, COWS, search_cows

print(render("Hello from my app", cow="owl", eyes="0.0"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Why I built it&lt;br&gt;
It started as a tiny script and grew into a layered, well-tested package:&lt;br&gt;
a pure rendering core with a thin CLI on top, a stable backwards-compatible&lt;br&gt;
API surface, and no hard dependencies on modern Python. It works on Linux,&lt;br&gt;
macOS, and Windows (including a legacy-console fallback for old cmd.exe).&lt;/p&gt;

&lt;p&gt;Try it today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/cowser/" rel="noopener noreferrer"&gt;https://pypi.org/project/cowser/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://rkriad585.github.io/Cowser/" rel="noopener noreferrer"&gt;https://rkriad585.github.io/Cowser/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/rkriad585/Cowser" rel="noopener noreferrer"&gt;https://github.com/rkriad585/Cowser&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  python #cli #cowsay #asciiart #opensource #rkriad585
&lt;/h1&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>rkriad585</category>
      <category>tools</category>
    </item>
    <item>
      <title>How I Built ActiveVPN: A Terminal Tool That Proves (or Exposes) Your VPN</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:36:07 +0000</pubDate>
      <link>https://dev.to/rkriad585/how-i-built-activevpn-a-terminal-tool-that-proves-or-exposes-your-vpn-38jg</link>
      <guid>https://dev.to/rkriad585/how-i-built-activevpn-a-terminal-tool-that-proves-or-exposes-your-vpn-38jg</guid>
      <description>&lt;p&gt;The problem&lt;br&gt;
Your VPN client shows a green "Connected" toggle. That's a marketing claim, not a proof. A tunnel can be up while DNS leaks, IPv6 bypasses the route, or your "anonymous" egress sits in a datacenter that any service can fingerprint.&lt;/p&gt;

&lt;p&gt;How ActiveVPN works&lt;br&gt;
The scan collects five groups of signals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Network interfaces — checks psutil.net_if_addrs() against patterns like tun, tap, utun, wg, ipsec, tailscale, zerotier.&lt;/li&gt;
&lt;li&gt;Processes — iterates running processes and matches them against known VPN/Tor binaries using exact/CLI-token matching (this removed a lot of naive-substring false positives, e.g. "vpn" matching random apps).&lt;/li&gt;
&lt;li&gt;External IP — queries ip-api.com, ipinfo.io, and ipapi.co in a failover chain for IP, ISP, country, hosting, and proxy flags.&lt;/li&gt;
&lt;li&gt;DNS — calls edns.ip-api.com to find the resolver IP your DNS queries actually go through.&lt;/li&gt;
&lt;li&gt;IPv4/IPv6 — fetches both via ipify to spot IPv6 leaks around an IPv4-only tunnel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Verdict scoring&lt;br&gt;
Each signal has a weight (interface 50, VPN process 40, Tor 35, hosting 25, proxy 30). The sum, capped at 100, maps to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;0-19 CLEAN&lt;/li&gt;
&lt;li&gt;20-39 SUSPICIOUS&lt;/li&gt;
&lt;li&gt;40-74 LIKELY VPN/PROXY&lt;/li&gt;
&lt;li&gt;75-100 VPN DETECTED&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extras worth mentioning&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kill switch: sudo activevpn --kill / --kill-force.&lt;/li&gt;
&lt;li&gt;Watch mode: activevpn --watch 30 with on_change callbacks for VPN-drop alerts.&lt;/li&gt;
&lt;li&gt;History &amp;amp; export: JSON/CSV/TXT from the platform data directory.&lt;/li&gt;
&lt;li&gt;Exit codes (0/1/2) so you can wire it into CI.&lt;/li&gt;
&lt;li&gt;Library API: import activevpn; result = activevpn.scan(); result.verdict.label.&lt;/li&gt;
&lt;li&gt;Docker image + GitHub Pages docs + full pytest suite running on 3 OSes across Python 3.8 and 3.12.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install&lt;br&gt;
pip install activevpn&lt;br&gt;
activevpn&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/rkriad585/ActiveVPN" rel="noopener noreferrer"&gt;https://github.com/rkriad585/ActiveVPN&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://rkriad585.github.io/ActiveVPN" rel="noopener noreferrer"&gt;https://rkriad585.github.io/ActiveVPN&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>rkriad585</category>
      <category>tools</category>
      <category>activevpn</category>
    </item>
    <item>
      <title>Share Files Over LAN with a QR Code - a tiny Python CLI</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Fri, 14 Aug 2026 12:14:52 +0000</pubDate>
      <link>https://dev.to/rkriad585/share-files-over-lan-with-a-qr-code-a-tiny-python-cli-2ba4</link>
      <guid>https://dev.to/rkriad585/share-files-over-lan-with-a-qr-code-a-tiny-python-cli-2ba4</guid>
      <description>&lt;p&gt;If you've ever needed to move a file from your computer to your phone&lt;br&gt;
(or to a colleague on the same Wi-Fi), you know the usual options are&lt;br&gt;
all slightly annoying: email, cloud drives, USB cables, chat apps that&lt;br&gt;
compress or require accounts.&lt;/p&gt;

&lt;p&gt;qrtransfer solves it with one command and one scan: it serves files&lt;br&gt;
over HTTP on your LAN and prints a QR code in the terminal. Scan it&lt;br&gt;
with your phone's camera and the download starts.&lt;/p&gt;

&lt;p&gt;Usage&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Share a file
qrtransfer myphoto.jpg

# Share a whole folder (auto-zipped)
qrtransfer builds/

# Share a text snippet
qrtransfer --text "hello world"

# Receive files from your phone
qrtransfer receive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Nice defaults, honest limits&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stops after the first successful download by default; --keep-alive
or --max-downloads N changes that.&lt;/li&gt;
&lt;li&gt;Unguessable tokens (secrets.token_urlsafe) so links aren't
guessable.&lt;/li&gt;
&lt;li&gt;Password via ?passed=SECRET or X-Password header; expiry returns
HTTP 410.&lt;/li&gt;
&lt;li&gt;--tls for self-signed HTTPS, --ipv6 supported, --clipboard copies
the URL.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Python 3.9+, stdlib http.server + ThreadingHTTPServer.&lt;/li&gt;
&lt;li&gt;psutil for interface/IP detection, platformdirs for config paths,
qrcode-terminal for the QR output.&lt;/li&gt;
&lt;li&gt;Streaming multipart parser for receive mode - large uploads never
buffer fully in memory, and filenames are sanitized against path
traversal.&lt;/li&gt;
&lt;li&gt;One mutable Session dataclass drives everything; no module globals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing &amp;amp; CI&lt;/p&gt;

&lt;p&gt;The repo ships a pytest suite (unit + in-process integration + CLI&lt;br&gt;
end-to-end) run across Ubuntu, Windows, and macOS on Python 3.9/3.11/&lt;br&gt;
3.13, plus ruff linting and pyright type-checking. It's also packaged&lt;br&gt;
as a Docker image (ghcr.io/rkriad585/qrtransfer) and published on&lt;br&gt;
PyPI as qrtransfer-lite.&lt;/p&gt;

&lt;p&gt;Install&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install qrtransfer-lite
# extras: [clipboard], [tls]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or from source:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/rkriad585/qrtransfer
cd qrtransfer &amp;amp;&amp;amp; pip install -e ".[dev]"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It's MIT licensed. Feedback and PRs welcome.&lt;/p&gt;

&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/rkriad585/qrtransfer" rel="noopener noreferrer"&gt;https://github.com/rkriad585/qrtransfer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://rkriad585.github.io/qrtransfer/" rel="noopener noreferrer"&gt;https://rkriad585.github.io/qrtransfer/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>rkriad585</category>
      <category>tools</category>
    </item>
    <item>
      <title>I Built a Zero-Dependency English Translator (Python, Stdlib Only)</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Fri, 14 Aug 2026 11:53:08 +0000</pubDate>
      <link>https://dev.to/rkriad585/i-built-a-zero-dependency-english-translator-python-stdlib-only-290d</link>
      <guid>https://dev.to/rkriad585/i-built-a-zero-dependency-english-translator-python-stdlib-only-290d</guid>
      <description>&lt;p&gt;Why&lt;br&gt;
Most "translator" projects lean on external APIs or heavyweight&lt;br&gt;
dependencies. I wanted to see how far I could get with nothing but the&lt;br&gt;
Python standard library — and have something genuinely usable at the&lt;br&gt;
end. The result: emtranslator, a dictionary-based English-to-Monsu&lt;br&gt;
translator with a CLI and an embeddable API.&lt;br&gt;
The Monsu language&lt;br&gt;
Monsu is fictional, invented for this project. Its vocabulary lives in&lt;br&gt;
a 90-entry dictionary mapping English words to monsu_1 through&lt;br&gt;
monsu_90.&lt;br&gt;
Design highlights&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokenizing is one regex: (\w+)|([^\w\s])|(\s+). Words get looked
up; punctuation and whitespace pass through untouched.&lt;/li&gt;
&lt;li&gt;Casing is preserved on the translated output — "Hello" → "Monsu_1".&lt;/li&gt;
&lt;li&gt;Unknown words are kept as-is and reported via missing_words().&lt;/li&gt;
&lt;li&gt;Reverse mode inverts the dictionary, so Monsu → English works out of
the box.&lt;/li&gt;
&lt;li&gt;The user dictionary is a flat TOML file at
&lt;code&gt;~/.config/neostore/emtranslator/config.toml&lt;/code&gt;, read and written by a
hand-rolled parser (because zero deps means zero deps).
CLI quick start
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;emtrans &lt;span class="s2"&gt;"Hello, world!"&lt;/span&gt;          &lt;span class="c"&gt;# Monsu_1, monsu_2!&lt;/span&gt;
emtrans &lt;span class="nt"&gt;--reverse&lt;/span&gt; &lt;span class="s2"&gt;"monsu_1"&lt;/span&gt;      &lt;span class="c"&gt;# hello&lt;/span&gt;
emtrans add hi monsu_91          &lt;span class="c"&gt;# persist a new word&lt;/span&gt;
emtrans &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="s2"&gt;"hello zebra"&lt;/span&gt;     &lt;span class="c"&gt;# shows missing words&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Library quick start&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;from&lt;/span&gt; &lt;span class="n"&gt;emtranslator&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Translator&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Translator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&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;span class="c1"&gt;# Monsu_1 monsu_2
&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hola&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;monsu_91&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;Testing &amp;amp; tooling&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;32 pytest tests covering the API and the CLI end-to-end.&lt;/li&gt;
&lt;li&gt;Full docs (mkdocs), a Docker image, and a logo.
Building it dependency-free was a fun constraint — it makes you reach
for the standard library instead of pulling in a package for every
small problem. Worth trying on your next side project.
→ &lt;a href="https://github.com/rkriad585/EMTranslator" rel="noopener noreferrer"&gt;https://github.com/rkriad585/EMTranslator&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rkriad585</category>
      <category>emtranslator</category>
      <category>opensource</category>
      <category>tools</category>
    </item>
    <item>
      <title>H9A: Count How Many Times a Digit Appears in Any Range</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Fri, 14 Aug 2026 09:24:22 +0000</pubDate>
      <link>https://dev.to/rkriad585/h9a-count-how-many-times-a-digit-appears-in-any-range-32a2</link>
      <guid>https://dev.to/rkriad585/h9a-count-how-many-times-a-digit-appears-in-any-range-32a2</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frikecpj5d1nap9k8z0ch.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frikecpj5d1nap9k8z0ch.png" alt=" " width="799" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A classic trick question: how many times does the digit 9 appear between 1 and 100? Most people answer 19. The correct answer is &lt;strong&gt;20&lt;/strong&gt; — 9, 19, 29, ..., 99 give 10 in the ones place, and 90–99 give 10 in the tens place. The number 99 is counted twice.&lt;/p&gt;

&lt;p&gt;I turned this into a small Python package, &lt;strong&gt;H9A&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and use
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install h9a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h9a                       # 9 in 1..100 -&amp;gt; 20
h9a --digit 0 --start 0 --end 9
h9a --json                # machine-readable output
h9a --screenshot          # terminal-style PNG

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why it's fast
&lt;/h2&gt;

&lt;p&gt;The first version iterated the range. A range of a billion numbers meant a billion iterations. I replaced it with a closed-form, per-place formula: for each decimal position, the count comes from division and modulo on the endpoints. Ranges up to 1,000,000,000,000 now resolve in microseconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extras
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rich&lt;/code&gt; colorized output, &lt;code&gt;pyfiglet&lt;/code&gt; ASCII banner, Pillow screenshots&lt;/li&gt;
&lt;li&gt;Library API: &lt;code&gt;count_digit()&lt;/code&gt; returns a per-place &lt;code&gt;DigitCount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;74 tests, ruff, mypy, pre-commit, CI docs + container publishing&lt;/li&gt;
&lt;li&gt;MIT-licensed, Python 3.8+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/rkriad585/h9a" rel="noopener noreferrer"&gt;https://github.com/rkriad585/h9a&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://rkriad585.github.io/h9a/" rel="noopener noreferrer"&gt;https://rkriad585.github.io/h9a/&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;PyPI:&lt;/strong&gt; &lt;a href="https://pypi.org/project/h9a/" rel="noopener noreferrer"&gt;https://pypi.org/project/h9a/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cli</category>
      <category>devops</category>
      <category>rkriad585</category>
    </item>
    <item>
      <title>LineSolv: A Natural-Language Calculator for Every Platform</title>
      <dc:creator>RK Riad Khan</dc:creator>
      <pubDate>Sat, 11 Jul 2026 15:03:32 +0000</pubDate>
      <link>https://dev.to/rkriad585/linesolv-a-natural-language-calculator-for-every-platform-4m47</link>
      <guid>https://dev.to/rkriad585/linesolv-a-natural-language-calculator-for-every-platform-4m47</guid>
      <description>&lt;h1&gt;
  
  
  LineSolv: A Natural-Language Calculator for Every Platform
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — Numi is beautiful but macOS-only. LineSolv brings the same idea to Linux, Windows, and macOS — built with Go + Wails for a ~25 MB binary that starts in under a second. Open source, MIT licensed, no accounts, no telemetry.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I've been a Numi user for years. The notepad-style calculator where you just &lt;em&gt;type&lt;/em&gt; what you mean — &lt;code&gt;20% of 150&lt;/code&gt;, &lt;code&gt;5 kg in pounds&lt;/code&gt;, &lt;code&gt;sin(pi/4)&lt;/code&gt; — and get instant results is genuinely one of those tools that changes how you work with numbers.&lt;/p&gt;

&lt;p&gt;But Numi is macOS-only.&lt;/p&gt;

&lt;p&gt;If you're on Linux or Windows, you're stuck with either the built-in calculator (which requires clicking buttons) or a full-blown spreadsheet app just to do quick math. There's a real gap in the market for a beautiful, keyboard-driven calculator that works everywhere.&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Go + Wails, Not Electron?
&lt;/h2&gt;

&lt;p&gt;I considered Electron first — it's the obvious choice for "build a desktop app with web technologies." But the numbers didn't add up:&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;Electron&lt;/th&gt;
&lt;th&gt;Go + Wails&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Binary size&lt;/td&gt;
&lt;td&gt;100–200 MB&lt;/td&gt;
&lt;td&gt;20–50 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory (idle)&lt;/td&gt;
&lt;td&gt;80–150 MB&lt;/td&gt;
&lt;td&gt;20–40 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Startup time&lt;/td&gt;
&lt;td&gt;2–5 seconds&lt;/td&gt;
&lt;td&gt;&amp;lt; 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native feel&lt;/td&gt;
&lt;td&gt;Heavy&lt;/td&gt;
&lt;td&gt;Lightweight&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Wails v2 lets you write the backend in Go and the frontend in whatever JS/TS framework you want (I used vanilla TypeScript + Tailwind). The Go backend compiles to a single native binary. The frontend runs in the system's native WebView — no bundled Chromium.&lt;/p&gt;

&lt;p&gt;The result: &lt;strong&gt;a ~25 MB app that starts instantly and uses almost no memory.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;LineSolv is a notepad-style calculator. You type natural language or math expressions on the left, and results appear instantly on the right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Natural Language That Actually Works
&lt;/h3&gt;

&lt;p&gt;You don't need to learn syntax. Just type what you'd say out loud:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;twenty five percent of 200          → 50
5 kg in pounds                      → 11.0231 lb
what is pi plus five                → 8.14159
2h30m in minutes                    → 150 min
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwwutthgje4qmcgl1m4a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwwutthgje4qmcgl1m4a.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The parser handles natural language (&lt;code&gt;twenty five&lt;/code&gt;, &lt;code&gt;half as much as 100&lt;/code&gt;), unit conversions across 100+ units in 14 categories, percentage math, and even purchase calculations (&lt;code&gt;3 items at $10 each with a 15% discount&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables and Context
&lt;/h3&gt;

&lt;p&gt;Lines reference each other automatically. Type &lt;code&gt;x = 42&lt;/code&gt; on one line, and &lt;code&gt;x * 2&lt;/code&gt; on the next line gives you &lt;code&gt;84&lt;/code&gt;. Use &lt;code&gt;of that&lt;/code&gt; or &lt;code&gt;then&lt;/code&gt; to chain results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100
+ 10%            → 110 (10% of previous result)
of that           → 121 (10% again)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step-by-Step Evaluation
&lt;/h3&gt;

&lt;p&gt;Hit &lt;code&gt;Ctrl+S&lt;/code&gt; to open the Steps panel and see exactly how your expression was parsed and computed — every operation, every intermediate value. Great for learning or debugging complex calculations.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue3kd15f1f9sihbxet6t.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue3kd15f1f9sihbxet6t.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Function Graphing
&lt;/h3&gt;

&lt;p&gt;Type &lt;code&gt;plot x^2&lt;/code&gt; or &lt;code&gt;graph sin(x)&lt;/code&gt; and a live chart renders in the Graph panel. Supports custom ranges (&lt;code&gt;plot x^2 from -10 to 10&lt;/code&gt;), multiple series, and Chart.js-powered interactive tooltips.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkzvixzkmecc1qo4m2zq4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkzvixzkmecc1qo4m2zq4.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple Notes, Persistent Storage
&lt;/h3&gt;

&lt;p&gt;Create as many calculation notebooks as you need. Everything persists to a local SQLite database. Drag to reorder, search across all notes, export to PDF, JSON, Markdown, or plain text.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6ilf6l7ssdc4lw7tmmv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6ilf6l7ssdc4lw7tmmv.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7 Themes
&lt;/h3&gt;

&lt;p&gt;Dark, Light, Neon, Red, Obsidian, Plasma, and Blood — switch instantly in Settings. Every theme is carefully crafted for readability and contrast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything Else
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;26 built-in math functions&lt;/strong&gt; — &lt;code&gt;sin&lt;/code&gt;, &lt;code&gt;cos&lt;/code&gt;, &lt;code&gt;sqrt&lt;/code&gt;, &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;round&lt;/code&gt;, &lt;code&gt;abs&lt;/code&gt;, &lt;code&gt;factorial&lt;/code&gt;, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live currency conversion&lt;/strong&gt; — USD, EUR, GBP, JPY, and more via exchange-rate API (with offline cache)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable shortcuts&lt;/strong&gt; — rebind any keyboard shortcut&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print with formatting&lt;/strong&gt; — A4 layout with note header, watermark, and page numbers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undo/Redo&lt;/strong&gt; — 200-entry history stack&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF export&lt;/strong&gt; — formatted documents with dates and page numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Parser
&lt;/h3&gt;

&lt;p&gt;The core is a recursive-descent parser in Go (~2,100 lines) with a 15-step natural language preprocessing pipeline. It handles operator precedence (PEMDAS), implicit multiplication (&lt;code&gt;2pi&lt;/code&gt;), chained operations, and over 100 unit definitions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;naturalize()&lt;/code&gt; function converts English words and phrases into tokenized math expressions before the parser sees them. It handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Word numbers (&lt;code&gt;twenty five&lt;/code&gt; → &lt;code&gt;25&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Percentage phrases (&lt;code&gt;10% of 200&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Unit conversions (&lt;code&gt;5 kg in pounds&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Purchase math (&lt;code&gt;3 items at $10 each with 15% discount&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Frontend
&lt;/h3&gt;

&lt;p&gt;Vanilla TypeScript, no framework. Just classes, DOM APIs, and Tailwind CSS. The app has 11 components, 2 stores, and a 200-entry undo/redo stack — all in ~3,000 lines.&lt;/p&gt;

&lt;p&gt;Key architectural decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No virtual DOM&lt;/strong&gt; — direct DOM manipulation with diffing for the line-number gutter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debounced evaluation&lt;/strong&gt; — 150ms debounce with stale-result detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy panel rendering&lt;/strong&gt; — panels build their DOM only when first opened&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Build
&lt;/h3&gt;

&lt;p&gt;Wails v2 handles the cross-compilation. One &lt;code&gt;wails build&lt;/code&gt; command produces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux: standalone binary + &lt;code&gt;.deb&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;macOS: &lt;code&gt;.dmg&lt;/code&gt; (Intel + Apple Silicon)&lt;/li&gt;
&lt;li&gt;Windows: NSIS installer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CI runs on GitHub Actions with automatic releases on tag push.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone and run&lt;/span&gt;
git clone https://github.com/rkriad585/LineSolv.git
&lt;span class="nb"&gt;cd &lt;/span&gt;LineSolv
wails dev

&lt;span class="c"&gt;# Or just download a release&lt;/span&gt;
&lt;span class="c"&gt;# https://github.com/rkriad585/LineSolv/releases&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LineSolv — is a lot works, but there's a lot more to build. If you've ever wished Numi worked on Linux, or you just want a fast, private calculator that respects your time, give it a try.&lt;/p&gt;

&lt;p&gt;Contributions welcome. Open an issue, send a PR, or just star the repo if you want to follow along.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/rkriad585/LineSolv" rel="noopener noreferrer"&gt;github.com/rkriad585/LineSolv&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; MIT&lt;br&gt;
&lt;strong&gt;Built with:&lt;/strong&gt; Go, Wails v2, TypeScript, Tailwind CSS, Vite&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
