<?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: Vanya Proskuriakov</title>
    <description>The latest articles on DEV Community by Vanya Proskuriakov (@vanyapr).</description>
    <link>https://dev.to/vanyapr</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%2F3976538%2Fd6af3c63-a108-4eb6-9d5f-a6cc8170d170.PNG</url>
      <title>DEV Community: Vanya Proskuriakov</title>
      <link>https://dev.to/vanyapr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vanyapr"/>
    <language>en</language>
    <item>
      <title>I Accidentally Built a Messenger That Consists of a Single HTML File</title>
      <dc:creator>Vanya Proskuriakov</dc:creator>
      <pubDate>Tue, 09 Jun 2026 19:52:29 +0000</pubDate>
      <link>https://dev.to/vanyapr/i-accidentally-built-a-messenger-that-consists-of-a-single-html-file-4bm2</link>
      <guid>https://dev.to/vanyapr/i-accidentally-built-a-messenger-that-consists-of-a-single-html-file-4bm2</guid>
      <description>&lt;h1&gt;
  
  
  I Accidentally Built a Messenger That Consists of a Single HTML File
&lt;/h1&gt;

&lt;p&gt;A few days ago I had a stupid thought.&lt;/p&gt;

&lt;p&gt;What is the minimum amount of technology required to send a message to your mom?&lt;/p&gt;

&lt;p&gt;Not billions of dollars worth of infrastructure.&lt;/p&gt;

&lt;p&gt;Not a distributed cluster.&lt;/p&gt;

&lt;p&gt;Not an end-to-end encrypted communication platform.&lt;/p&gt;

&lt;p&gt;Not a super app.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Mom, please cook macaroni."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more I thought about it, the stranger modern messaging systems started to look.&lt;/p&gt;

&lt;p&gt;Eventually I ended up building a messenger that consists of a single HTML file and stores messages in Git repositories.&lt;/p&gt;

&lt;p&gt;Unfortunately, it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Original Joke
&lt;/h2&gt;

&lt;p&gt;The project started as a joke.&lt;/p&gt;

&lt;p&gt;What if a messenger had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no backend&lt;/li&gt;
&lt;li&gt;no database&lt;/li&gt;
&lt;li&gt;no registration&lt;/li&gt;
&lt;li&gt;no phone numbers&lt;/li&gt;
&lt;li&gt;no servers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first this sounded ridiculous.&lt;/p&gt;

&lt;p&gt;Then I realized Git already knows how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;store data&lt;/li&gt;
&lt;li&gt;synchronize data&lt;/li&gt;
&lt;li&gt;keep history&lt;/li&gt;
&lt;li&gt;work offline&lt;/li&gt;
&lt;li&gt;replicate repositories&lt;/li&gt;
&lt;li&gt;merge changes&lt;/li&gt;
&lt;li&gt;handle identities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;p&gt;Git already solves most of the problems messaging systems need to solve.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The architecture is surprisingly boring.&lt;/p&gt;

&lt;p&gt;Frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML
CSS
JavaScript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Synchronization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git pull
git fetch
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SA6E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mom, please cook macaroni"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1749340800&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's basically it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Entire Client Is One File
&lt;/h2&gt;

&lt;p&gt;The most ridiculous part is the client.&lt;/p&gt;

&lt;p&gt;The client is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messenger.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not an installer.&lt;/p&gt;

&lt;p&gt;Not a package.&lt;/p&gt;

&lt;p&gt;Not Electron.&lt;/p&gt;

&lt;p&gt;Not a launcher.&lt;/p&gt;

&lt;p&gt;A file.&lt;/p&gt;

&lt;p&gt;You double-click it.&lt;/p&gt;

&lt;p&gt;The messenger starts.&lt;/p&gt;

&lt;p&gt;I wanted to see how far I could push the idea of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What if HTML is the application?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer turned out to be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Much further than expected.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Privacy
&lt;/h2&gt;

&lt;p&gt;Macaroni Messenger does not promise privacy.&lt;/p&gt;

&lt;p&gt;In fact, it explicitly promises the opposite.&lt;/p&gt;

&lt;p&gt;If your repository is public:&lt;/p&gt;

&lt;p&gt;your messages are public.&lt;/p&gt;

&lt;p&gt;If your repository is private:&lt;/p&gt;

&lt;p&gt;everyone with repository access can read them.&lt;/p&gt;

&lt;p&gt;If you need privacy:&lt;/p&gt;

&lt;p&gt;install an encryption plugin.&lt;/p&gt;

&lt;p&gt;Good luck.&lt;/p&gt;

&lt;p&gt;I find this approach more honest than pretending that every communication system is somehow magical.&lt;/p&gt;




&lt;h2&gt;
  
  
  Identity
&lt;/h2&gt;

&lt;p&gt;Every client gets a tiny identifier.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SA6E
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do I guarantee uniqueness?&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Did I try?&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;Will collisions happen?&lt;/p&gt;

&lt;p&gt;Probably.&lt;/p&gt;

&lt;p&gt;Will this matter for a family chat?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;The entire philosophy of the project is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not make things complicated when they can be funny.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This does not prevent them from being real software.&lt;/p&gt;




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

&lt;p&gt;The most absurd part of the story is how the project was built.&lt;/p&gt;

&lt;p&gt;I have a Codex subscription.&lt;/p&gt;

&lt;p&gt;One evening I wrote a roadmap.&lt;/p&gt;

&lt;p&gt;Then I went to sleep.&lt;/p&gt;

&lt;p&gt;Literally.&lt;/p&gt;

&lt;p&gt;While I was asleep, the coding agent continued implementing the roadmap.&lt;/p&gt;

&lt;p&gt;I woke up the next morning.&lt;/p&gt;

&lt;p&gt;The messenger existed.&lt;/p&gt;

&lt;p&gt;This repository is the result of that mistake.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Git?
&lt;/h2&gt;

&lt;p&gt;People keep asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why Git?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer is always the same:&lt;/p&gt;

&lt;p&gt;Because Git already knows how to store files.&lt;/p&gt;

&lt;p&gt;Most modern software introduces complexity because complexity already exists somewhere else.&lt;/p&gt;

&lt;p&gt;Macaroni Messenger does the opposite.&lt;/p&gt;

&lt;p&gt;It aggressively reuses things that already exist.&lt;/p&gt;

&lt;p&gt;Need synchronization?&lt;/p&gt;

&lt;p&gt;Git.&lt;/p&gt;

&lt;p&gt;Need history?&lt;/p&gt;

&lt;p&gt;Git.&lt;/p&gt;

&lt;p&gt;Need replication?&lt;/p&gt;

&lt;p&gt;Git.&lt;/p&gt;

&lt;p&gt;Need backups?&lt;/p&gt;

&lt;p&gt;Git.&lt;/p&gt;

&lt;p&gt;Need offline support?&lt;/p&gt;

&lt;p&gt;Git.&lt;/p&gt;

&lt;p&gt;Need transport?&lt;/p&gt;

&lt;p&gt;Still Git.&lt;/p&gt;




&lt;h2&gt;
  
  
  Is It A Joke?
&lt;/h2&gt;

&lt;p&gt;Partially.&lt;/p&gt;

&lt;p&gt;The funny thing is that the more I worked on it, the less it felt like a joke.&lt;/p&gt;

&lt;p&gt;The user interface looks like a messenger.&lt;/p&gt;

&lt;p&gt;The messages are delivered.&lt;/p&gt;

&lt;p&gt;The history works.&lt;/p&gt;

&lt;p&gt;Search works.&lt;/p&gt;

&lt;p&gt;Synchronization works.&lt;/p&gt;

&lt;p&gt;The architecture is surprisingly resilient.&lt;/p&gt;

&lt;p&gt;At some point I realized I had accidentally built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a messenger&lt;/li&gt;
&lt;li&gt;a Git client&lt;/li&gt;
&lt;li&gt;an append-only event log&lt;/li&gt;
&lt;li&gt;a distributed communication protocol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all at the same time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does This Exist?
&lt;/h2&gt;

&lt;p&gt;Macaroni Messenger is not a political statement.&lt;/p&gt;

&lt;p&gt;It is not a manifesto.&lt;/p&gt;

&lt;p&gt;It is not trying to replace Telegram.&lt;/p&gt;

&lt;p&gt;It exists because I wanted to answer a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much software do we actually need to send a message?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer turned out to be:&lt;/p&gt;

&lt;p&gt;Less than I thought.&lt;/p&gt;

&lt;p&gt;A lot less.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Status
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Works&lt;/li&gt;
&lt;li&gt;One HTML file&lt;/li&gt;
&lt;li&gt;Git backend&lt;/li&gt;
&lt;li&gt;No servers&lt;/li&gt;
&lt;li&gt;1000% vibecoded&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vanyapr/makaroshki?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And yes.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Mom, please cook macaroni&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;using a Git commit.&lt;/p&gt;

&lt;p&gt;Unfortunately, it works.&lt;/p&gt;

</description>
      <category>git</category>
      <category>html</category>
      <category>showdev</category>
      <category>sideprojects</category>
    </item>
  </channel>
</rss>
