<?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: Alex Sofroniev</title>
    <description>The latest articles on DEV Community by Alex Sofroniev (@alexsofroniev).</description>
    <link>https://dev.to/alexsofroniev</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F870337%2Fba35e590-5a4b-41e5-b217-b98fc7070ab7.jpg</url>
      <title>DEV Community: Alex Sofroniev</title>
      <link>https://dev.to/alexsofroniev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexsofroniev"/>
    <language>en</language>
    <item>
      <title>ShipDocs vs Google CodeWiki: Same Idea, One Critical Difference</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Tue, 05 May 2026 13:29:50 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/shipdocs-vs-google-codewiki-same-idea-one-critical-difference-b5g</link>
      <guid>https://dev.to/alexsofroniev/shipdocs-vs-google-codewiki-same-idea-one-critical-difference-b5g</guid>
      <description>&lt;p&gt;Google just validated an entire market with one launch.&lt;/p&gt;

&lt;p&gt;On November 13, 2025, Google launched Code Wiki — an AI-powered platform that scans any public repository and generates structured, interactive documentation with a Gemini-powered chat agent. Architecture diagrams. Per-component breakdowns. File-cited answers.&lt;/p&gt;

&lt;p&gt;It's a genuinely impressive product.&lt;/p&gt;

&lt;p&gt;There's just one problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It only works on public repos.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Private repos — the ones with your actual IP, your production services, your unreleased products — are listed as "coming soon." And nobody knows when they will ship.&lt;/p&gt;

&lt;p&gt;That's the gap ShipDocs was built to fill. And it's been filling it since before Google shipped Code Wiki.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Google CodeWiki Actually Does
&lt;/h2&gt;

&lt;p&gt;To be fair to Google, Code Wiki is excellent for what it does.&lt;/p&gt;

&lt;p&gt;Point it at any public GitHub repository and it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates a complete structured wiki automatically&lt;/li&gt;
&lt;li&gt;Creates architecture diagrams that update when code changes&lt;/li&gt;
&lt;li&gt;Provides a Gemini-powered chat agent that answers questions with links to the exact source files&lt;/li&gt;
&lt;li&gt;Keeps documentation live and updated as the codebase evolves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For open source maintainers, for teams evaluating public libraries, for developers trying to understand an unfamiliar public codebase — it's genuinely useful.&lt;/p&gt;

&lt;p&gt;The problem is that most professional development happens in private repositories. And Code Wiki can't touch those.&lt;/p&gt;




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

&lt;p&gt;Think about what lives in your private repos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your production backend services&lt;/li&gt;
&lt;li&gt;Your unreleased product features&lt;/li&gt;
&lt;li&gt;Your proprietary algorithms&lt;/li&gt;
&lt;li&gt;Your internal tooling&lt;/li&gt;
&lt;li&gt;Your client work&lt;/li&gt;
&lt;li&gt;Your startup's entire codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are exactly the repos where documentation matters most. These are the codebases that new developers struggle to understand. These are the projects where senior developers waste weeks answering the same onboarding questions over and over.&lt;/p&gt;

&lt;p&gt;Code Wiki doesn't help with any of them. Not yet. And when it does, you probably will have to set up and use Gemini CLI.&lt;/p&gt;




&lt;h2&gt;
  
  
  How ShipDocs Compares
&lt;/h2&gt;

&lt;p&gt;ShipDocs does what Code Wiki does, but for your private repos, cloud-hosted, with no infrastructure required.&lt;/p&gt;

&lt;p&gt;Here's the direct comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;ShipDocs&lt;/th&gt;
&lt;th&gt;Google CodeWiki&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auto-generated from real source&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public repo support&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Private repo support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Right now&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;❌ Coming soon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-component module breakdown&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI chat grounded in your code&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File path citations in answers&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No manual writing required&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI: push your cwd in one command&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;⏳ Waitlist&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Editable Markdown you own and export&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256-GCM encrypted at rest&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Never used for AI training&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-technical team access&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No local setup or infrastructure&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free plan available&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two columns look similar on paper. The execution is fundamentally different.&lt;/p&gt;




&lt;h2&gt;
  
  
  What ShipDocs Does That CodeWiki Doesn't
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Private repos, encrypted end-to-end
&lt;/h3&gt;

&lt;p&gt;ShipDocs encrypts every project with AES-256-GCM, with per-project keys stored in a KMS-backed vault. Your code never hits the database in plaintext. It's never used to train any AI model — not ours, not anyone else's.&lt;/p&gt;

&lt;p&gt;Connect via GitHub or GitLab. Upload a .zip. Or push from your terminal in seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud hosted — no infrastructure required
&lt;/h3&gt;

&lt;p&gt;You don't need to run anything locally. No CLI to maintain. No servers to configure. Sign in, connect your repo, and docs are ready in under 2 minutes. If ShipDocs disappears, you already own your Markdown — it lives wherever you export it.&lt;/p&gt;

&lt;p&gt;Google's private repo version will require running their Gemini CLI. That's a meaningful operational overhead for any team.&lt;/p&gt;

&lt;h3&gt;
  
  
  For the terminal natives
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; shipdocs.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire install. Auth via browser, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shipdocs upload
→ scanning 1,284 files…
→ detecting components…
✓ found: backend · frontend · workers · cli · migrations
→ writing docs &lt;span class="o"&gt;[&lt;/span&gt;9/9]
✓ &lt;span class="k"&gt;done in &lt;/span&gt;2m 14s
&lt;span class="nv"&gt;$ &lt;/span&gt;open shipdocs.sh/p/your-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your codebase documented without leaving your terminal. The domain is the install command.&lt;/p&gt;

&lt;h3&gt;
  
  
  For non-technical teammates
&lt;/h3&gt;

&lt;p&gt;This is where ShipDocs goes somewhere Code Wiki doesn't even try to go.&lt;/p&gt;

&lt;p&gt;Documentation isn't just for developers. Marketing needs to understand what's being built. Sales needs to explain it to clients. Product managers need to know what's possible. Founders need to understand their own product.&lt;/p&gt;

&lt;p&gt;ShipDocs generates docs written for humans, not just engineers. Non-technical teammates can read, search, and chat with the documentation without needing to understand the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markdown you own
&lt;/h3&gt;

&lt;p&gt;Your docs are standard Markdown. Export them anytime. Deploy to GitHub Pages, Notion, Confluence, your own servers — wherever you want. You're not locked into ShipDocs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Google launching Code Wiki is meaningful validation for this entire category.&lt;/p&gt;

&lt;p&gt;When Google enters a space, it confirms the problem is real. It confirms developers actually want automated documentation from their repos. It confirms the market is large enough to matter.&lt;/p&gt;

&lt;p&gt;But Google entering a space with a public-only solution also confirms something else: the private repo problem is harder to solve, and harder to trust a hyperscaler with.&lt;/p&gt;

&lt;p&gt;Your private code is your IP. The decision to hand it to Google's infrastructure — a company whose entire business model is built on data — is not trivial. ShipDocs is built by a developer who needed this tool for his own team, using infrastructure specifically designed for private code privacy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Practical Question
&lt;/h2&gt;

&lt;p&gt;If you have public repos and want free, google-integrated documentation: Code Wiki is excellent. Use it.&lt;/p&gt;

&lt;p&gt;If you have private repos — which is most production development — you need something that works today, not when Google ships their waitlisted CLI extension.&lt;/p&gt;

&lt;p&gt;ShipDocs works today. Free plan includes 2 private repos and 100 AI chat messages per month. No credit card required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Five Free Tools (No Account Required)
&lt;/h2&gt;

&lt;p&gt;While you're deciding, ShipDocs has five free tools that work on any public repo right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/readme" rel="noopener noreferrer"&gt;AI README Generator&lt;/a&gt;&lt;/strong&gt; — Paste a repo URL, get a professional README instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/complexity" rel="noopener noreferrer"&gt;Repo Complexity Score&lt;/a&gt;&lt;/strong&gt; — 0-100 complexity score with breakdown by component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/tweet" rel="noopener noreferrer"&gt;Explain Repo in a Tweet&lt;/a&gt;&lt;/strong&gt; — One sentence that explains any repo. Surprisingly useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/dockerfile" rel="noopener noreferrer"&gt;AI Dockerfile Generator&lt;/a&gt;&lt;/strong&gt; — Production-ready Dockerfile from any public repo URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/audit" rel="noopener noreferrer"&gt;Production Readiness Audit&lt;/a&gt;&lt;/strong&gt; — Scores any repo 0-100 across documentation, CI/testing, secrets hygiene, dependency health, and dev environment. Takes seconds.&lt;/p&gt;

&lt;p&gt;No signup. No account. Just paste a repo URL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Early Access
&lt;/h2&gt;

&lt;p&gt;ShipDocs is in early access. First 500 members get founding member pricing locked in forever:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Founding Price&lt;/th&gt;
&lt;th&gt;Normal Price&lt;/th&gt;
&lt;th&gt;Repos&lt;/th&gt;
&lt;th&gt;Messages/mo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;$7.20/mo&lt;/td&gt;
&lt;td&gt;$9/mo&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$23.20/mo&lt;/td&gt;
&lt;td&gt;$29/mo&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;349 founding spots remaining as of publishing.&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;&lt;a href="https://shipdocs.sh" rel="noopener noreferrer"&gt;shipdocs.sh&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by &lt;a href="https://x.com/DevOffScript" rel="noopener noreferrer"&gt;@DevOffScript&lt;/a&gt;. Follow along on &lt;a href="https://x.com/shipdocs_" rel="noopener noreferrer"&gt;@shipdocs_&lt;/a&gt; as we build in public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions or thoughts? Drop them in the comments — I read and reply to everything.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>documentation</category>
      <category>google</category>
      <category>tooling</category>
    </item>
    <item>
      <title>I Spent 3 Years Looking for This Tool. It Didn't Exist. So I Built It.</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Mon, 04 May 2026 12:34:51 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/i-spent-3-years-looking-for-this-tool-it-didnt-exist-so-i-built-it-6ja</link>
      <guid>https://dev.to/alexsofroniev/i-spent-3-years-looking-for-this-tool-it-didnt-exist-so-i-built-it-6ja</guid>
      <description>&lt;p&gt;Every time we hired a new developer, the same nightmare started.&lt;/p&gt;

&lt;p&gt;Week 1: &lt;em&gt;"Alex, how does this service work?"&lt;/em&gt;&lt;br&gt;
Week 2: &lt;em&gt;"Alex, where does this connect to?"&lt;/em&gt;&lt;br&gt;
Week 3: still pulling me and my senior devs away from real work.&lt;/p&gt;

&lt;p&gt;I managed a team building software across multiple projects — Java backends, ESP32 firmware in C/C++, frontend apps. The codebase was real, complex, and completely undocumented in any readable form.&lt;/p&gt;

&lt;p&gt;New hires weren't the problem. The codebase was.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Tools I Tried (And Why They All Failed)
&lt;/h2&gt;

&lt;p&gt;I spent a long time looking for a fix before I decided to build one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Confluence&lt;/strong&gt; — Someone has to write it first. We never did. Nobody does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notion wikis&lt;/strong&gt; — Outdated before you finish typing. Great intentions, zero maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NotebookLM&lt;/strong&gt; — Genuinely great product. Doesn't support code files. Dead end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT/Claude&lt;/strong&gt; — Paste your entire codebase manually or through CLI always updated manually. Sure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swimm and Mintlify&lt;/strong&gt; — The closest things to what I needed. Both require manual input, both are expensive for private repos, and neither lets your non-technical teammates actually use them.&lt;/p&gt;

&lt;p&gt;Nothing solved the full problem: &lt;em&gt;scan my private codebase automatically, generate structured docs, and let my entire team — devs and non-devs — chat with them.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What I Actually Needed
&lt;/h2&gt;

&lt;p&gt;Let me be specific about the problem, because I think a lot of dev leads feel this but can't articulate it clearly.&lt;/p&gt;

&lt;p&gt;The real cost of undocumented codebases isn't the onboarding time. It's the &lt;strong&gt;interruption tax&lt;/strong&gt; on your senior developers.&lt;/p&gt;

&lt;p&gt;Every time a new hire asks a question:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A senior dev context-switches out of deep work&lt;/li&gt;
&lt;li&gt;Answers a question they've answered 6 times before&lt;/li&gt;
&lt;li&gt;Loses 20-90 minutes of productive flow
Multiply that by every new hire, every week, across every project. It's not a small problem. It's thousands of hours of your best engineers' time wasted every year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it's not just new devs. Marketing needs to understand what's being built. Sales needs to explain it to clients. Product managers need to know what's possible. Your entire non-technical team is flying blind.&lt;/p&gt;


&lt;h2&gt;
  
  
  So I Built ShipDocs
&lt;/h2&gt;

&lt;p&gt;The concept is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Point it at your private repos (GitHub, GitLab, Bitbucket, zip upload or CLI)&lt;/li&gt;
&lt;li&gt;AI scans every file and generates structured documentation automatically&lt;/li&gt;
&lt;li&gt;Your whole team browses the docs or chats with them directly
No manual writing. No outdated wikis. No copy-pasting code into any AI tool.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The docs are structured into real components — Overview, Architecture, Backend, Frontend, Workers, CLI, Migrations — whatever your actual codebase looks like. Not one-size-fits-all pages.&lt;/p&gt;

&lt;p&gt;And the chat cites file paths. Every answer tells you exactly where in the codebase the information comes from. No hallucinated APIs. No vague summaries.&lt;/p&gt;


&lt;h2&gt;
  
  
  For Those Who Live in the Terminal
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; shipdocs.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. One command installs the CLI. Auth via browser, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shipdocs
→ scanning 1,284 files…
→ detecting components…
✓ found: backend · frontend · workers · cli · migrations
→ writing docs &lt;span class="o"&gt;[&lt;/span&gt;6/9]
✓ &lt;span class="k"&gt;done in &lt;/span&gt;2m 14s
&lt;span class="nv"&gt;$ &lt;/span&gt;open shipdocs.sh/p/your-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your entire codebase documented without leaving your terminal.&lt;/p&gt;




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

&lt;p&gt;ShipDocs auto-detects your stack — languages, frameworks, package managers — and writes the run instructions automatically.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;TypeScript, JavaScript, React, Vue, Svelte&lt;/li&gt;
&lt;li&gt;Python, Django, FastAPI, Flask&lt;/li&gt;
&lt;li&gt;Java, Spring Boot, Maven, Gradle&lt;/li&gt;
&lt;li&gt;C, C++, ESP32 firmware, Arduino, PlatformIO&lt;/li&gt;
&lt;li&gt;Go, Rust, PHP, Swift&lt;/li&gt;
&lt;li&gt;Bun, Elysia, Hono, Express&lt;/li&gt;
&lt;li&gt;Docker, Kubernetes, Terraform&lt;/li&gt;
&lt;li&gt;Monorepos, microservices, micro-CLIs&lt;/li&gt;
&lt;li&gt;and many more...
If you write it, ShipDocs reads it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Security Question (I Know You're Thinking It)
&lt;/h2&gt;

&lt;p&gt;Private code is private. I built this for teams with real IP in their repos. Here's what we do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AES-256-GCM encryption at rest&lt;/strong&gt; — per-project keys, KMS-backed vault&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never used for AI training&lt;/strong&gt; — your code is never used to train any model, ours or anyone else's. We pay the model providers directly and use TEE models so you stay out of training data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GDPR-aligned&lt;/strong&gt; — right to erasure, defined retention windows, 90-day grace before hard delete&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - &lt;strong&gt;Nothing usable hits the database in plaintext&lt;/strong&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Three Free Tools (No Account Needed)
&lt;/h2&gt;

&lt;p&gt;While you're deciding whether ShipDocs is right for you, I built three free tools that work on public repos right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/readme" rel="noopener noreferrer"&gt;AI README Generator&lt;/a&gt;&lt;/strong&gt; — Paste a repo URL, get a professional README in seconds. No more blank page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/complexity" rel="noopener noreferrer"&gt;Repo Complexity Score&lt;/a&gt;&lt;/strong&gt; — Scan any public repo and get a complexity report. Weirdly addictive to run on repos you know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://shipdocs.sh/tools/tweet" rel="noopener noreferrer"&gt;Explain Repo in a Tweet&lt;/a&gt;&lt;/strong&gt; — Paste a repo URL, get a one-sentence explanation. Great for understanding unfamiliar codebases fast.&lt;/p&gt;

&lt;p&gt;All three are free, no account needed. Try them on a repo you know well and see how accurate the output is.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack (Since You'll Ask)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; TanStack Start (React, file-based routing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; ElysiaJS + Bun (fast, excellent WebSocket support for streaming)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL on Neon&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth:&lt;/strong&gt; Better-Auth (magic link, GitHub, GitLab, Bitbucket OAuth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; OpenRouter — different models per plan tier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Polar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Cloudflare Pages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - &lt;strong&gt;Domain:&lt;/strong&gt; shipdocs.sh (yes, the domain is the install command)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Pricing and Early Access
&lt;/h2&gt;

&lt;p&gt;ShipDocs is in early access right now. 151 devs have already joined and the feedback is amazing! First 500 members get founding pricing locked in forever:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Founding Price&lt;/th&gt;
&lt;th&gt;Normal Price&lt;/th&gt;
&lt;th&gt;Repos&lt;/th&gt;
&lt;th&gt;Messages/mo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;$7.20/mo&lt;/td&gt;
&lt;td&gt;$9/mo&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;$23.20/mo&lt;/td&gt;
&lt;td&gt;$29/mo&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Free plan is genuinely free — no credit card, no trial period, just two repos and 100 messages a month forever.&lt;/p&gt;

&lt;p&gt;Early access → &lt;strong&gt;&lt;a href="https://shipdocs.sh" rel="noopener noreferrer"&gt;shipdocs.sh&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  One Last Thing
&lt;/h2&gt;

&lt;p&gt;If you've ever been the senior dev who got pulled out of deep work to explain the same module for the sixth time — this is for you.&lt;/p&gt;

&lt;p&gt;If you've ever been the new hire who felt like they were drowning in an undocumented codebase for the first three weeks — this is for you.&lt;/p&gt;

&lt;p&gt;If you've ever been the founder who couldn't explain to their marketing team what the engineers are actually building — this is for you.&lt;/p&gt;

&lt;p&gt;Stop writing docs. Start shipping them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by &lt;a href="https://x.com/DevOffScript" rel="noopener noreferrer"&gt;@DevOffScript&lt;/a&gt; — follow along as I build in public.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions, feedback, or brutal honesty → drop a comment below or find me on X.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Part 1: Building Zero-Knowledge Encryption That Actually Works</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Fri, 04 Jul 2025 13:12:13 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/part-1-building-zero-knowledge-encryption-that-actually-works-2ijf</link>
      <guid>https://dev.to/alexsofroniev/part-1-building-zero-knowledge-encryption-that-actually-works-2ijf</guid>
      <description>&lt;p&gt;&lt;em&gt;How I built client-side AES-256-GCM encryption for GHOSTVAULT in 72 hours&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem Everyone Ignores
&lt;/h3&gt;

&lt;p&gt;When I started building GHOSTVAULT during the World's Largest Hackathon, I had a simple requirement: &lt;strong&gt;true zero-knowledge architecture&lt;/strong&gt;. Not the marketing buzzword kind, but the real deal — where even I, the creator, cannot access user data.&lt;/p&gt;

&lt;p&gt;After 72 hours of intense development, I learned that implementing real zero-knowledge encryption isn't just about choosing the right algorithm. It's about solving problems that crypto tutorials never mention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do you derive keys securely from passwords?&lt;/li&gt;
&lt;li&gt;What happens when users choose weak passwords in a zero-knowledge system?&lt;/li&gt;
&lt;li&gt;How do you handle encryption failures gracefully?&lt;/li&gt;
&lt;li&gt;How do you make security user-friendly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This series covers the real implementation challenges I faced building what became the most advanced cybersecurity platform ever created on Bolt.new.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Most "Zero-Knowledge" Apps Aren't
&lt;/h3&gt;

&lt;p&gt;Let me be blunt: most apps claiming "zero-knowledge" are lying.&lt;/p&gt;

&lt;p&gt;True zero-knowledge means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ &lt;strong&gt;No password recovery&lt;/strong&gt; — if you lose your key, your data is gone forever&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;No server-side decryption&lt;/strong&gt; — the server never sees unencrypted data&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;No debugging user data&lt;/strong&gt; — developers can't inspect user information&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;No "forgot password" magic&lt;/strong&gt; — there's no backdoor, period&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an app offers password recovery or customer support can "help you access your data," it's not zero-knowledge. It's security theater.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real Implementation: AES-256-GCM + PBKDF2
&lt;/h3&gt;

&lt;p&gt;Here's what actual zero-knowledge encryption looks like in production:&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;class&lt;/span&gt; &lt;span class="nc"&gt;ZeroKnowledgeEncryption&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;algorithm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ivLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&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;encoder&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;TextEncoder&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;keyMaterial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deriveBits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deriveKey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SHA-256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;keyMaterial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;encrypt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;decrypt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;generateSalt&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="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;generateIV&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="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ivLength&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;encrypt&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;key&lt;/span&gt;&lt;span class="p"&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;encoder&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;TextEncoder&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;iv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateIV&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;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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;stringify&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;combined&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;byteLength&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iv&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;async&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encryptedData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&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;iv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encryptedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ivLength&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="nx"&gt;encryptedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ivLength&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;decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;data&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;decoder&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;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&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;decoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrypted&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &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="k"&gt;throw&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Decryption failed: Invalid key or corrupted data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;bufferToBase64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&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="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCharCode&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;base64ToBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base64&lt;/span&gt;&lt;span class="p"&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;binary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base64&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;buffer&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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="nx"&gt;buffer&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;&lt;strong&gt;Why this works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PBKDF2 with 100,000 iterations&lt;/strong&gt; makes brute force attacks computationally expensive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random salts&lt;/strong&gt; prevent rainbow table attacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AES-256-GCM&lt;/strong&gt; provides both encryption and authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Crypto API&lt;/strong&gt; ensures cryptographically secure operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Password Security Challenge
&lt;/h3&gt;

&lt;p&gt;The biggest UX challenge in zero-knowledge systems? &lt;strong&gt;Password strength vs usability.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Users want simple passwords. Zero-knowledge encryption demands strong ones. There's no middle ground because there's no password recovery.&lt;/p&gt;

&lt;p&gt;My solution was building a comprehensive password strength calculator:&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;calculatePasswordStrength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;score&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;feedback&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// Length is most important for cryptographic security&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;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Use at least 12 characters (20+ recommended)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Character variety checks&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Add uppercase letters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Add lowercase letters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Add numbers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;!@#$%^&amp;amp;*()_+&lt;/span&gt;&lt;span class="se"&gt;\-&lt;/span&gt;&lt;span class="sr"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\[\]&lt;/span&gt;&lt;span class="sr"&gt;{};':"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="sr"&gt;|,.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;?&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Add special characters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Determine security level&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;level&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;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;good&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fair&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weak&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;feedback&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;The visual feedback component:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PasswordStrengthIndicator&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&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;strength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculatePasswordStrength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&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;levelColors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weak&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff4444&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fair&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ffbb33&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;good&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00C851&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#007E33&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password-strength&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strength-bars&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;20&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="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
                        &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`strength-bar &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; 
                            &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;threshold&lt;/span&gt; 
                                &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;levelColors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
                                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#e0e0e0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
                        &lt;span class="p"&gt;}}&lt;/span&gt;
                    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="p"&gt;))}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strength-text&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&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="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strength-feedback&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&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="nx"&gt;tip&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                    &lt;span class="p"&gt;))}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;
  
  
  React Implementation: The Real Demo
&lt;/h3&gt;

&lt;p&gt;Here's how the actual encryption flow works in my demo:&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;App&lt;/span&gt;&lt;span class="p"&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;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPassword&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dataToEncrypt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDataToEncrypt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;encryptedResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setEncryptedResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;decryptedResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDecryptedResult&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentSalt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentSalt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;isProcessing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&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="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&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;ZeroKnowledgeEncryption&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;handleEncrypt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;dataToEncrypt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter both password and data to encrypt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Generate fresh salt for this encryption session&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSalt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nf"&gt;setCurrentSalt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Derive key from password&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Encrypt the data&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dataToEncrypt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;demo_data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Convert to base64 for display&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;base64Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bufferToBase64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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;saltBase64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bufferToBase64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nf"&gt;setEncryptedResult&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;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;saltBase64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iv&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &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="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Encryption failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;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;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dataToEncrypt&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="c1"&gt;// Rest of component...&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;Key insights from this implementation:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fresh salt per encryption&lt;/strong&gt; - Never reuse salts, even for the same user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No persistent key storage&lt;/strong&gt; - Keys are derived on-demand from passwords&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit error handling&lt;/strong&gt; - Clear feedback when crypto operations fail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base64 encoding&lt;/strong&gt; - Makes binary data human-readable for debugging&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Performance at Scale: Real Numbers
&lt;/h3&gt;

&lt;p&gt;GHOSTVAULT encrypts breach data for 50+ users daily. Here are the real performance metrics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key derivation:&lt;/strong&gt; ~200ms (PBKDF2 with 100K iterations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption rate:&lt;/strong&gt; ~500 operations/second (small records)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser compatibility:&lt;/strong&gt; 98% (Web Crypto API support)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure rate:&lt;/strong&gt; &amp;lt;0.1% (mostly weak passwords)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Complete Working Demo
&lt;/h3&gt;

&lt;p&gt;I've built a complete demo that shows real zero-knowledge encryption in action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/alexsofroniev/zero-knowledge-client-side-demo" rel="noopener noreferrer"&gt;→ Try the Complete Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Considerations You Can't Ignore
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Never Store Keys&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NEVER do this&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;encryptionKey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// CORRECT - derive keys on-demand&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;storedSalt&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;2. Handle Browser Differences&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crypto&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="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subtle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;createError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;ERROR_TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BROWSER_SUPPORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Browser does not support required cryptographic features&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please use a modern browser with Web Crypto API support (Chrome, Firefox, Safari, Edge).&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Secure Random Generation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use cryptographically secure random&lt;/span&gt;
&lt;span class="nf"&gt;generateSalt&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="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;generateIV&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="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&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;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ivLength&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;
  
  
  The UX Challenge: Making Security Usable
&lt;/h3&gt;

&lt;p&gt;The biggest challenge isn't technical—it's making users understand the trade-offs:&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;PasswordWarning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;password&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;strength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validatePassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password-warning&lt;/span&gt;&lt;span class="dl"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isValid&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="err"&gt;⚠️&lt;/span&gt; &lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;forget&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;PERMANENTLY&lt;/span&gt; &lt;span class="nx"&gt;lost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
          &lt;span class="nx"&gt;We&lt;/span&gt; &lt;span class="nx"&gt;cannot&lt;/span&gt; &lt;span class="nx"&gt;recover&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strength-meter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;Strength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;5
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;This is Part 1 of a 4-part series on implementing zero-knowledge systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1:&lt;/strong&gt; Client-side AES-256-GCM encryption ← &lt;em&gt;You are here&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2:&lt;/strong&gt; Memory management with large datasets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3:&lt;/strong&gt; Zero-Knowledge Authentication &amp;amp; Multi-Device Sync
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4:&lt;/strong&gt; Encrypted search that actually works&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Bottom Line
&lt;/h3&gt;

&lt;p&gt;Real zero-knowledge encryption is unforgiving. There's no password recovery, no customer support magic, and no shortcuts.&lt;/p&gt;

&lt;p&gt;But when done right, it creates something powerful: &lt;strong&gt;software that protects users even from its own creators.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GHOSTVAULT proves this is possible. Built in 72 hours, serving real users, processing real data — all while maintaining true zero-knowledge architecture.&lt;/p&gt;

&lt;p&gt;The key is starting with solid crypto fundamentals and building user experience on top of uncompromising security.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building GHOSTVAULT taught me that the most important security feature isn't what you can do — it's what you can't do. True zero-knowledge means giving up control to give users privacy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to see the complete code?&lt;/strong&gt; The full working demo with all source code is available in my GitHub repo. Star it if this helped you understand real zero-knowledge implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/alexsofroniev/zero-knowledge-client-side-demo" rel="noopener noreferrer"&gt;→ Get the Complete Source Code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions about the implementation?&lt;/strong&gt; Drop them in the comments. I'll be writing detailed follow-ups based on what people want to know most.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Built the Most Advanced Bolt.new Project Ever - And I'm Hitting Platform Limits</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Mon, 23 Jun 2025 19:07:24 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/i-built-the-most-advanced-boltnew-project-ever-and-im-hitting-platform-limits-32mp</link>
      <guid>https://dev.to/alexsofroniev/i-built-the-most-advanced-boltnew-project-ever-and-im-hitting-platform-limits-32mp</guid>
      <description>&lt;p&gt;&lt;em&gt;How I pushed a no-code platform beyond its boundaries with enterprise cybersecurity&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I built what might be the most technically complex Bolt.new project in the platform's history. GHOSTVAULT is an enterprise-grade cybersecurity platform with client-side encryption, multi-API orchestration, and advanced threat correlation. The twist? I'm literally hitting Bolt.new's project size limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem That Started It All
&lt;/h2&gt;

&lt;p&gt;Existing breach monitoring tools are broken:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise solutions:&lt;/strong&gt; $50K+ annual licenses, months of implementation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free checkers:&lt;/strong&gt; Single database lookups that miss 60% of actual breaches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SMB gap:&lt;/strong&gt; Nothing exists for businesses that need enterprise features without enterprise overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a developer, this frustrated me. Why should comprehensive cybersecurity be locked behind massive paywalls?&lt;/p&gt;

&lt;h2&gt;
  
  
  The 72-Hour Challenge
&lt;/h2&gt;

&lt;p&gt;I decided to build a solution for the World's Largest Hackathon. My goal: prove that enterprise-grade cybersecurity could be built rapidly using modern no-code platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; GHOSTVAULT - a comprehensive breach intelligence platform that aggregates data from 5+ sources and provides real-time risk analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://ghostvault.tech" rel="noopener noreferrer"&gt;https://ghostvault.tech&lt;/a&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Core Enterprise Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-source intelligence:&lt;/strong&gt; Simultaneous queries across HaveIBeenPwned, DeHashed, IntelligenceX, BreachDirectory, Snusbase + 3 secret ones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client-side encryption:&lt;/strong&gt; AES-256-GCM implementation with zero-knowledge architecture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced correlation:&lt;/strong&gt; Intelligent deduplication and risk scoring across all sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time monitoring:&lt;/strong&gt; Background scanning with instant breach notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Technical Complexity
&lt;/h3&gt;

&lt;p&gt;This isn't your typical no-code project. I implemented:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advanced Cryptography&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom Web Crypto API integration for client-side encryption&lt;/li&gt;
&lt;li&gt;Secure key derivation using PBKDF2&lt;/li&gt;
&lt;li&gt;Zero-knowledge architecture ensuring complete privacy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;API Orchestration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simultaneous coordination of 5+ external breach intelligence services&lt;/li&gt;
&lt;li&gt;Intelligent rate limiting and error handling&lt;/li&gt;
&lt;li&gt;Real-time data correlation and deduplication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Enterprise State Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex UI flows with persistent encrypted storage&lt;/li&gt;
&lt;li&gt;Background worker processes for continuous monitoring&lt;/li&gt;
&lt;li&gt;Advanced caching strategies for performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hitting Platform Boundaries
&lt;/h2&gt;

&lt;p&gt;Here's where things got interesting. I started receiving warnings from Bolt.new:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Project approaching size limits"&lt;/li&gt;
&lt;li&gt;"Consider removing unused files"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to create a comprehensive .bolt/ignore file with 100+ exclusions just to keep the project running. This includes optimizing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bundle sizes and asset loading&lt;/li&gt;
&lt;li&gt;Component lazy loading strategies&lt;/li&gt;
&lt;li&gt;Intelligent caching mechanisms&lt;/li&gt;
&lt;li&gt;Performance optimization for large datasets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The irony:&lt;/strong&gt; I built enterprise software so complex it's breaking the platform's assumptions about project scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Proves About No-Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Myth: "No-Code Can't Handle Enterprise Complexity"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Reality:&lt;/strong&gt; GHOSTVAULT implements features that would typically require months of traditional development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advanced cryptographic operations&lt;/li&gt;
&lt;li&gt;Multi-service API orchestration&lt;/li&gt;
&lt;li&gt;Complex data correlation algorithms&lt;/li&gt;
&lt;li&gt;Enterprise-grade security architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Myth: "No-Code Means Simple Applications"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Reality:&lt;/strong&gt; I'm processing 100MB+ of data client-side, coordinating 500+ API calls per session, and maintaining sub-2-second response times for complex security analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Myth: "No-Code Limits Innovation"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Reality:&lt;/strong&gt; The rapid development cycle actually accelerated innovation. I could test advanced features immediately rather than waiting weeks for implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Development Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Worked Incredibly Well
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rapid iteration:&lt;/strong&gt; Testing complex features in real-time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web API integration:&lt;/strong&gt; Modern browser capabilities work seamlessly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component architecture:&lt;/strong&gt; Complex UI flows remain maintainable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance scaling:&lt;/strong&gt; Platform handles enterprise-grade data processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where I Hit Limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project size constraints:&lt;/strong&gt; Large applications need optimization strategies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced debugging:&lt;/strong&gt; Complex state flows require creative troubleshooting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom infrastructure needs:&lt;/strong&gt; Eventually need backend for user management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundle optimization:&lt;/strong&gt; Manual intervention required for complex apps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Learning Curve
&lt;/h3&gt;

&lt;p&gt;Building enterprise features on no-code required rethinking traditional development approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Client-side first:&lt;/strong&gt; Moving complex logic to the browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API composition:&lt;/strong&gt; Orchestrating multiple services without backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State management:&lt;/strong&gt; Handling enterprise complexity in React&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance optimization:&lt;/strong&gt; Making advanced features feel responsive&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Business Impact Beyond Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hackathon Results
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Competing for &lt;strong&gt;Grand Prize&lt;/strong&gt; in World's Largest Hackathon&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical achievement&lt;/strong&gt; recognized by cybersecurity professionals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform partnership&lt;/strong&gt; discussions initiated with StackBlitz team&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social proof&lt;/strong&gt; building around "most advanced project ever"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Market Validation Speed
&lt;/h3&gt;

&lt;p&gt;Traditional approach: 6+ months to MVP, $100K+ development costs&lt;br&gt;
No-code approach: 72 hours to production-ready platform, $0 development costs&lt;/p&gt;

&lt;p&gt;This speed enabled immediate market validation without massive upfront investment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Industry Reception
&lt;/h3&gt;

&lt;p&gt;The cybersecurity community's response has been fascinating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security professionals&lt;/strong&gt; asking about enterprise deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; questioning how advanced features were implemented&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business leaders&lt;/strong&gt; interested in rapid development methodologies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investors&lt;/strong&gt; curious about scalable no-code approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Platform Optimization Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Performance Challenges
&lt;/h3&gt;

&lt;p&gt;As complexity grew, I had to implement enterprise-grade optimization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lazy loading&lt;/strong&gt; for breach detection modules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent caching&lt;/strong&gt; with configurable TTL strategies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundle splitting&lt;/strong&gt; for faster initial load times&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background processing&lt;/strong&gt; to maintain UI responsiveness&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memory Management
&lt;/h3&gt;

&lt;p&gt;Processing large breach datasets client-side required careful memory management and garbage collection optimization, especially for mobile devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons for the Developer Community
&lt;/h2&gt;

&lt;h3&gt;
  
  
  No-Code Isn't "Toy Code" or "Vibe Coding"
&lt;/h3&gt;

&lt;p&gt;GHOSTVAULT proves that modern no-code platforms can handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Complex cryptographic operations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise security requirements&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Advanced data processing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production-ready scalability&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rapid Validation is Revolutionary
&lt;/h3&gt;

&lt;p&gt;The ability to build and test enterprise features in hours rather than months changes everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Market validation&lt;/strong&gt; happens before major investment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature iteration&lt;/strong&gt; cycles accelerate dramatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical feasibility&lt;/strong&gt; proves itself immediately&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business model validation&lt;/strong&gt; occurs in real-time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Future of Development
&lt;/h3&gt;

&lt;p&gt;This project suggests we're entering an era where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complex applications&lt;/strong&gt; can be prototyped rapidly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise features&lt;/strong&gt; don't require months of development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical innovation&lt;/strong&gt; happens at unprecedented speed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer productivity&lt;/strong&gt; multiplies through better tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Technical Evolution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom backend integration&lt;/strong&gt; for user authentication and billing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise admin dashboard&lt;/strong&gt; for team management features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API development&lt;/strong&gt; for third-party security tool integrations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced analytics&lt;/strong&gt; for breach trend analysis and prediction&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Business Development
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freemium model&lt;/strong&gt; with basic breach checking free&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic PRO plan&lt;/strong&gt; at $6.9/month for comprehensive monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise tier&lt;/strong&gt; at $299/month with team features and API access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;White-label licensing&lt;/strong&gt; for security vendors and consultants&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Future Platform Collaboration
&lt;/h3&gt;

&lt;p&gt;I've reached out to the StackBlitz team about potential collaboration opportunities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documenting optimization strategies&lt;/strong&gt; for complex applications hitting platform limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing architectural patterns&lt;/strong&gt; that work at enterprise scale on no-code platforms
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributing insights&lt;/strong&gt; about platform evolution based on real-world edge case usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating educational content&lt;/strong&gt; about advanced no-code techniques and limitations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to help improve the platform for developers building complex applications while sharing learnings with the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Industry Implications
&lt;/h3&gt;

&lt;p&gt;If enterprise cybersecurity can be built in 72 hours on a no-code platform, what other "complex" industries are ripe for disruption?&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer Productivity
&lt;/h3&gt;

&lt;p&gt;This project changed my perspective on software development. When you can validate enterprise ideas in days rather than months, innovation accelerates exponentially.&lt;/p&gt;

&lt;h3&gt;
  
  
  Democratization of Technology
&lt;/h3&gt;

&lt;p&gt;GHOSTVAULT proves that advanced technical capabilities are becoming accessible to smaller teams and individual developers. The barriers to building enterprise software are collapsing.&lt;/p&gt;

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

&lt;p&gt;Building the most advanced Bolt.new project ever taught me that the limitations we assume about no-code platforms often exist more in our minds than in reality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise complexity&lt;/strong&gt; is achievable on modern no-code platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rapid development&lt;/strong&gt; doesn't mean sacrificing technical sophistication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform limitations&lt;/strong&gt; often inspire creative optimization solutions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical innovation&lt;/strong&gt; happens faster when development friction disappears&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future of software development isn't about choosing between speed and complexity - it's about having both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources &amp;amp; Discussion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://ghostvault.tech" rel="noopener noreferrer"&gt;https://ghostvault.tech&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Technical Screenshots:&lt;/strong&gt; &lt;a href="https://snipboard.io/elRVgO.jpg" rel="noopener noreferrer"&gt;Platform warnings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions for the community:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's the most complex project you've built on a no-code platform?&lt;/li&gt;
&lt;li&gt;How do you handle the transition from rapid prototyping to production infrastructure?&lt;/li&gt;
&lt;li&gt;What other enterprise use cases could benefit from this rapid development approach?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Follow my journey:&lt;/strong&gt; Building enterprise software at startup speed, one no-code project at a time.&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>cybersecurity</category>
      <category>webdev</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>🚨 Your Site Is Down Right Now (And You Don't Even Know It)</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Wed, 18 Jun 2025 17:00:29 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/your-site-is-down-right-now-and-you-dont-even-know-it-3398</link>
      <guid>https://dev.to/alexsofroniev/your-site-is-down-right-now-and-you-dont-even-know-it-3398</guid>
      <description>&lt;p&gt;&lt;strong&gt;Let me guess...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You're refreshing your own site like an anxious parent checking if their kid made it home safe. Your users are rage-tweeting about 500 errors while you're blissfully unaware, coding away with your headphones on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sound familiar?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Wait, the API has been down for 3 hours?"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;"Why is our conversion rate tanking today?"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;"When did this break? Yesterday? Last week??"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Stop playing Russian roulette with your uptime.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Meet ZeroToPing — Monitoring Without the Highway Robbery
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://zerotoping.com" rel="noopener noreferrer"&gt;ZeroToPing&lt;/a&gt; because every monitoring tool out there is either criminally expensive, frustratingly limited, or designed by people who clearly hate developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 What It Actually Does (No Corporate BS)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monitors everything&lt;/strong&gt; — websites, APIs, microservices, that sketchy third-party integration you depend on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actually useful free plan&lt;/strong&gt; — not a glorified demo that expires in 14 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean, modern interface&lt;/strong&gt; — built this decade, not during the Bush administration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real email alerts&lt;/strong&gt; — when your site breaks, you'll know instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professional status pages&lt;/strong&gt; — no ugly "Powered by" branding ruining your reputation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero setup friction&lt;/strong&gt; — start monitoring in under 60 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💸 Pricing That Won't Bankrupt Your Startup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;FREE Plan&lt;/strong&gt; (Actually Generous)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;5 monitors&lt;/strong&gt; — perfect for side projects and MVPs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15-minute checks&lt;/strong&gt; — catch issues before they become disasters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5 status pages&lt;/strong&gt; — look professional even when bootstrapping&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email alerts included&lt;/strong&gt; — because monitoring without alerts is just data hoarding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No credit card required&lt;/strong&gt; — sign up and start monitoring immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PRO Plan&lt;/strong&gt; ($1.99/mo — &lt;em&gt;Seriously, Under Two Dollars&lt;/em&gt;)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited monitors&lt;/strong&gt; — monitor your entire digital empire&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1-minute checks&lt;/strong&gt; — near real-time monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited status pages&lt;/strong&gt; — scale without arbitrary limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero branding&lt;/strong&gt; — your pages, your brand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All future features&lt;/strong&gt; — webhooks, SMS alerts, custom domains&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤬 Why Every Popular Tool Is Hot Garbage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UptimeRobot?&lt;/strong&gt; Free plan gives you 5-minute intervals but only if you sacrifice your firstborn. Want decent monitoring? $8/month for 10 monitors. &lt;strong&gt;TEN.&lt;/strong&gt; Need 100 monitors? $34/month. It's like they're personally offended by your success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pingdom?&lt;/strong&gt; $15/month minimum and the interface looks like it was designed by someone who learned web design from a 2005 WordPress theme. Plus they'll upsell you to death.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StatusPage by Atlassian?&lt;/strong&gt; $29/month just to tell people your site is broken. That's more than most people pay for Netflix, Disney+, and Spotify combined. For a status page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Site24x7?&lt;/strong&gt; Tries to do everything, succeeds at nothing. You need a PhD in enterprise software just to set up basic monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Datadog?&lt;/strong&gt; Great if you enjoy $500+/month bills and explaining to your CFO why monitoring costs more than your server infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Relic?&lt;/strong&gt; "Observability" is just a fancy word for "we'll charge you $200/month for charts you'll never look at."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better Stack (formerly Better Uptime)?&lt;/strong&gt; Slick marketing, but $29/month for 10 monitors? Come on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ZeroToPing?&lt;/strong&gt; Built by a developer who got tired of this pricing insanity and just wanted monitoring that doesn't require a mortgage.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎪 The "Oh Shit" Moment Every Founder Has
&lt;/h2&gt;

&lt;p&gt;You launch on Product Hunt. Hit #1. Traffic explodes. Your $5/month VPS melts like butter in a microwave. You find out 4 hours later when your mom texts asking why your site won't load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't be that founder.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💀 What Happens When You Skip Monitoring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Revenue evaporates&lt;/strong&gt; — every minute of downtime = money bleeding out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO rankings tank&lt;/strong&gt; — Google punishes unreliable sites harder than a disappointed parent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users never come back&lt;/strong&gt; — first impressions are everything, and 500 errors aren't charming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reputation implodes&lt;/strong&gt; — "unreliable" is startup cancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sleep disappears&lt;/strong&gt; — 3 AM anxiety refreshes become your new hobby&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Start Monitoring in 60 Seconds (Actually)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Go to&lt;/strong&gt; &lt;a href="https://zerotoping.com" rel="noopener noreferrer"&gt;zerotoping.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign up&lt;/strong&gt; (no 47-field forms or enterprise questionnaires)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add your URLs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sleep better tonight&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No credit card hostage situations. No sales calls from Brad in enterprise solutions. No free trials that auto-charge your card.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Perfect For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Solo developers&lt;/strong&gt; tired of enterprise tools built for 200-person DevOps teams&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indie hackers&lt;/strong&gt; who need professional monitoring without VC-funded pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small teams&lt;/strong&gt; that want to spend money on features, not monitoring overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anyone&lt;/strong&gt; who thinks paying $34+/month for uptime monitoring is absolutely deranged&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔗 Stop Getting Robbed by Monitoring Companies
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://zerotoping.com" rel="noopener noreferrer"&gt;→ Try ZeroToPing Now&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your bank account (and your sanity) will thank you.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; — If you're paying more for monitoring than you pay for your actual servers, you're doing it wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.P.S.&lt;/strong&gt; — I actually respond to feature requests and ship fast. Try getting that kind of attention from the enterprise giants charging you $500/month.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drop your monitoring horror stories below 👇 — especially the pricing nightmares that made you question capitalism.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tired of setting up Stripe and Auth from scratch? Me too.</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Wed, 16 Apr 2025 11:49:17 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/tired-of-setting-up-stripe-and-auth-from-scratch-me-too-46fa</link>
      <guid>https://dev.to/alexsofroniev/tired-of-setting-up-stripe-and-auth-from-scratch-me-too-46fa</guid>
      <description>&lt;h2&gt;
  
  
  Why I Built a SaaS Boilerplate Generator Instead of Repeating Myself Again
&lt;/h2&gt;

&lt;p&gt;If you’ve ever started a SaaS project from scratch, you know the routine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up Auth&lt;/li&gt;
&lt;li&gt;Add Stripe billing&lt;/li&gt;
&lt;li&gt;Style a dashboard&lt;/li&gt;
&lt;li&gt;Configure a UI framework&lt;/li&gt;
&lt;li&gt;Plug in PostgreSQL&lt;/li&gt;
&lt;li&gt;Set up emails and SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s all &lt;strong&gt;before&lt;/strong&gt; you even start building the product you &lt;em&gt;actually&lt;/em&gt; want to launch.&lt;/p&gt;

&lt;p&gt;I’ve done it way too many times. And it’s always the same pain.&lt;/p&gt;

&lt;p&gt;So I built something that finally fixes it.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Introducing &lt;a href="https://getzerotosaas.com/waitlist" rel="noopener noreferrer"&gt;ZeroToSaaS&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ZeroToSaaS&lt;/strong&gt; is a boilerplate &lt;strong&gt;builder&lt;/strong&gt; — not just another GitHub repo.&lt;/p&gt;

&lt;p&gt;You choose your stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI framework (Tailwind, ShadCN, or MUI)&lt;/li&gt;
&lt;li&gt;Auth type (email/password, social)&lt;/li&gt;
&lt;li&gt;Dashboard theme (light/dark)&lt;/li&gt;
&lt;li&gt;Stripe setup (one-time or subscription)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you export a clean, production-grade SaaS codebase with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Auth + roles&lt;/li&gt;
&lt;li&gt;✅ Stripe billing&lt;/li&gt;
&lt;li&gt;✅ PostgreSQL + Prisma&lt;/li&gt;
&lt;li&gt;✅ Resend emails&lt;/li&gt;
&lt;li&gt;✅ SEO config&lt;/li&gt;
&lt;li&gt;✅ API keys&lt;/li&gt;
&lt;li&gt;✅ Full documentation&lt;/li&gt;
&lt;li&gt;✅ Lifetime updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No subscriptions. No lock-in. No setup hell.&lt;/p&gt;

&lt;p&gt;Just configure. Export. Launch.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 We're In Waitlist Mode
&lt;/h2&gt;

&lt;p&gt;ZeroToSaaS is launching soon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💥 100 early access spots at $99
&lt;/li&gt;
&lt;li&gt;🔥 Special deal for &lt;a href="https://uneed.best/tool/zerotosaas" rel="noopener noreferrer"&gt;Uneed&lt;/a&gt; users: $79 with code &lt;strong&gt;UNEED79&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎯 Already 28+ devs signed up&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're tired of starting from scratch — or want to finally ship your idea faster — join the waitlist here:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://getzerotosaas.com/waitlist" rel="noopener noreferrer"&gt;https://getzerotosaas.com/waitlist&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  P.S.:
&lt;/h3&gt;

&lt;p&gt;We’re going live on &lt;a href="https://devhunt.org/tool/zerotosaas" rel="noopener noreferrer"&gt;DevHunt&lt;/a&gt; next week — I’d love your feedback when we do.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I Rebuilt PlayCSS to Be Addictive on Purpose — Here’s How (and Why)</title>
      <dc:creator>Alex Sofroniev</dc:creator>
      <pubDate>Fri, 28 Mar 2025 18:05:11 +0000</pubDate>
      <link>https://dev.to/alexsofroniev/i-rebuilt-playcss-to-be-addictive-on-purpose-heres-how-and-why-43pn</link>
      <guid>https://dev.to/alexsofroniev/i-rebuilt-playcss-to-be-addictive-on-purpose-heres-how-and-why-43pn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Most learning platforms try to teach you. I wanted to rewire you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I run PlayCSS — a daily UI challenge platform to help frontend devs sharpen their CSS through real-world practice.&lt;/p&gt;

&lt;p&gt;It used to be a basic playground for CSS. Then I realized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Practice doesn’t stick without pressure. Progress doesn’t happen without psychology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I rebuilt the platform from scratch—with behavioral design at the core.&lt;/p&gt;

&lt;p&gt;Here’s what I added (and why it matters):&lt;/p&gt;

&lt;h2&gt;
  
  
  🔥 1. Streak Counter (Don’t Break the Chain)
&lt;/h2&gt;

&lt;p&gt;Humans are addicted to streaks.&lt;/p&gt;

&lt;p&gt;If you’ve ever used Duolingo, GitHub commits, or Snapchat, you know how powerful it is to see:&lt;br&gt;
&lt;em&gt;“You’ve shown up X days in a row.”&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So I added it.&lt;br&gt;
Submit a challenge every day = your streak grows.&lt;br&gt;
Miss a day? You lose it all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s brutal. But it works.&lt;br&gt;
Daily consistency builds real skill. Period.&lt;/p&gt;

&lt;h2&gt;
  
  
  👑 2. Public Profiles and Shareable Submissions (Because Reputation Drives Effort)
&lt;/h2&gt;

&lt;p&gt;Your submissions now live on a shareable page.&lt;br&gt;
This isn’t just for clout—it’s for accountability.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“When I know someone can see my code, I write it better.”&lt;br&gt;
– Beatris&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And now, you can:&lt;/p&gt;

&lt;p&gt;Show off your progress&lt;/p&gt;

&lt;p&gt;Share your profile on Twitter, LinkedIn, or with potential employers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use PlayCSS as your dev portfolio&lt;/strong&gt; (built in public)&lt;/p&gt;

&lt;h2&gt;
  
  
  📣 3. One-Click Social Sharing
&lt;/h2&gt;

&lt;p&gt;Finished a challenge?&lt;br&gt;
You’re &lt;strong&gt;one click away&lt;/strong&gt; from posting it directly to Twitter, Reddit, or LinkedIn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It builds your brand&lt;/li&gt;
&lt;li&gt;It attracts other devs&lt;/li&gt;
&lt;li&gt;It locks in your habit with public commitment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎁 4. Referral System (Because You Shouldn’t Learn Alone)
&lt;/h2&gt;

&lt;p&gt;I launched a new referral system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1 friend = 7 days of PRO&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Stack referrals → Never pay again&lt;/li&gt;
&lt;li&gt;5 friends = PRO+ Badge + Leaderboard ranking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's simple: You bring people in, and you get rewarded.&lt;br&gt;
And you build momentum with your circle.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 5. Motivation Nudges (Yes, They’re on Purpose)
&lt;/h2&gt;

&lt;p&gt;Every time you build a streak or fall off, PlayCSS responds.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hit a new milestone? &lt;strong&gt;Motivational boost.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Miss a day? You’ll get a guilt trip (designed to push you).&lt;/li&gt;
&lt;li&gt;Keep showing up? You’ll get noticed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built these nudges to mess with your brain in the best way.&lt;br&gt;
Because you don’t need more theory—you need identity transformation.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚔️ Why I Did This
&lt;/h2&gt;

&lt;p&gt;I wasn’t trying to make another learning platform.&lt;br&gt;
I was trying to make a system that makes you dangerous.&lt;/p&gt;

&lt;p&gt;Something that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builds real CSS skills&lt;/li&gt;
&lt;li&gt;Rewards consistent action&lt;/li&gt;
&lt;li&gt;Reinforces your reputation&lt;/li&gt;
&lt;li&gt;Feeds your competitive drive&lt;/li&gt;
&lt;li&gt;Actually sticks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;PlayCSS 2.0 isn’t a tool. It’s a training ground.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👉 Want to Try It?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start your streak today → &lt;a href="https://www.playcss.app" rel="noopener noreferrer"&gt;https://www.playcss.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Build your profile&lt;/li&gt;
&lt;li&gt;Invite a friend&lt;/li&gt;
&lt;li&gt;Don’t break the chain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're tired of passive tutorials and want something that actually builds you up—this is for you.&lt;/p&gt;

&lt;p&gt;Hit me in the comments if you try it. I’ll be watching 👀&lt;/p&gt;

&lt;p&gt;– Alex Sofroniev&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
