<?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: Mansi Kumawat</title>
    <description>The latest articles on DEV Community by Mansi Kumawat (@mansi_kumawat_d51607efff8).</description>
    <link>https://dev.to/mansi_kumawat_d51607efff8</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4111320%2F264aa13a-e5af-4cbd-b3eb-134e732a9c10.jpg</url>
      <title>DEV Community: Mansi Kumawat</title>
      <link>https://dev.to/mansi_kumawat_d51607efff8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mansi_kumawat_d51607efff8"/>
    <language>en</language>
    <item>
      <title>Building Z-RevixDB Without Dependencies: What We Had to Rebuild</title>
      <dc:creator>Mansi Kumawat</dc:creator>
      <pubDate>Sat, 05 Sep 2026 16:05:25 +0000</pubDate>
      <link>https://dev.to/mansi_kumawat_d51607efff8/building-z-revixdb-without-dependencies-what-we-had-to-rebuild-f5d</link>
      <guid>https://dev.to/mansi_kumawat_d51607efff8/building-z-revixdb-without-dependencies-what-we-had-to-rebuild-f5d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Building Z-RevixDB Without Dependencies: What We Had to Rebuild&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Z-RevixDB — Data That Remembers&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Modern software development makes it easy to build powerful applications. Need an HTTP server? Install a framework. Need database access? Install an ORM. Need search? Install a search engine. Need object comparison? Install a library.&lt;br&gt;
But what happens when you are told:&lt;br&gt;
"Your dependency manifest must be empty"&lt;br&gt;
That was the challenge behind Z-RevixDB, our attempt to build a useful versioned data storage and recovery platform using only the standard library.&lt;br&gt;
The goal wasn't simply to remove packages. The real challenge was understanding what those packages were actually doing for us and rebuilding only the functionality we genuinely needed.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The Problem We Wanted to Solve&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Most data systems are primarily concerned with the current state of data.&lt;br&gt;
A record might look like:&lt;br&gt;
{&lt;br&gt;
  "name": "John Doe",&lt;br&gt;
  "plan": "Basic",&lt;br&gt;
  "status": "Active",&lt;br&gt;
  "credit_limit": 500000&lt;br&gt;
}&lt;br&gt;
Later, someone changes the plan:&lt;br&gt;
Basic → Pro&lt;br&gt;
and the credit limit:&lt;br&gt;
₹5,00,000 → ₹8,00,000&lt;/p&gt;

&lt;p&gt;The current state is easy to see.&lt;br&gt;
But important questions remain:&lt;br&gt;
What changed?&lt;br&gt;
When did it change?&lt;br&gt;
What was the previous state?&lt;br&gt;
Why was it changed?&lt;br&gt;
Can we inspect the old state?&lt;br&gt;
Can we safely recover it?&lt;br&gt;
This led us to build Z-RevixDB — Data That Remembers.&lt;br&gt;
Instead of treating an update as a replacement, Z-RevixDB treats it as a new version.&lt;br&gt;
V1 → V2 → V3 → V4&lt;br&gt;
The history becomes part of the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Zero-Dependency Constraint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For this hackathon, we couldn't simply install our preferred tools.&lt;br&gt;
Normally, a project like this could involve frameworks, database abstraction layers, HTTP libraries, validation libraries, search libraries, and comparison utilities.&lt;br&gt;
Instead, we started asking a different question:&lt;br&gt;
What does this package actually provide, and can we build the required part ourselves using the standard library?&lt;br&gt;
That became one of the most interesting parts of the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Normally Would Have Used&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our replacement strategy looked roughly like this:&lt;br&gt;
&lt;strong&gt;Normally------- ----Z-RevixDB&lt;/strong&gt;&lt;br&gt;
Flask / FastAPI-------http.server &amp;amp; custom rounting&lt;br&gt;&lt;br&gt;
SQLAlchemy------------sqlite3&lt;br&gt;
Requests--------------urllib / http.client&lt;br&gt;
Pydantic--------------Custom validation&lt;br&gt;
DeepDiff--------------difflib + custom comparison logic&lt;br&gt;
Elasticsearch / Whoosh---Custom inverted index&lt;br&gt;
External hashing library--hashlib&lt;br&gt;
File utilities-------pathlib&lt;br&gt;
UUID package---------uuid&lt;br&gt;
Date/time libraries---datetime&lt;/p&gt;

&lt;p&gt;The important part is that we didn't copy third-party source code into the project.&lt;/p&gt;

&lt;p&gt;We used the primitives available in the language itself and implemented the application-specific functionality ourselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building the Web Layer&lt;/strong&gt;&lt;br&gt;
One of the first questions was:&lt;br&gt;
How do we create a web application without Flask or FastAPI?&lt;/p&gt;

&lt;p&gt;Python's standard library already provides http.server.&lt;br&gt;
That gave us the foundation for handling HTTP requests.&lt;br&gt;
We then implemented the application-level routing and request handling ourselves.&lt;br&gt;
Conceptually:&lt;/p&gt;

&lt;p&gt;Browser&lt;br&gt;
   ↓&lt;br&gt;
HTTP Server&lt;br&gt;
   ↓&lt;br&gt;
Request Routing&lt;br&gt;
   ↓&lt;br&gt;
Application Logic&lt;br&gt;
   ↓&lt;br&gt;
Storage / Version Engine&lt;/p&gt;

&lt;p&gt;This was a good reminder that frameworks don't create HTTP—they provide convenient abstractions around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building Versioned Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The heart of Z-RevixDB is the version engine.&lt;br&gt;
Instead of:&lt;/p&gt;

&lt;p&gt;Update Record&lt;br&gt;
     ↓&lt;br&gt;
Overwrite Old Data&lt;br&gt;
we use:&lt;br&gt;
Create Record&lt;br&gt;
     ↓&lt;br&gt;
Version 1&lt;br&gt;
     ↓&lt;br&gt;
Modify Record&lt;br&gt;
     ↓&lt;br&gt;
Version 2&lt;br&gt;
     ↓&lt;br&gt;
Modify Again&lt;br&gt;
     ↓&lt;br&gt;
Version 3&lt;/p&gt;

&lt;p&gt;Each version can retain information such as:&lt;/p&gt;

&lt;p&gt;Record identifier&lt;br&gt;
Version number&lt;br&gt;
Data snapshot&lt;br&gt;
Timestamp&lt;br&gt;
Commit message&lt;br&gt;
Integrity information&lt;/p&gt;

&lt;p&gt;SQLite, through Python's sqlite3 module, provides persistent storage without requiring an external database server or ORM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Interesting Part: Recovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the design decisions that became particularly important was recovery.&lt;br&gt;
Suppose we have:&lt;br&gt;
V1 → V2 → V3 → V4&lt;br&gt;
and V4 contains an incorrect value.&lt;br&gt;
A tempting implementation would be to replace V4 with V2.&lt;br&gt;
But that would destroy history.&lt;br&gt;
Instead, Z-RevixDB creates a new version:&lt;br&gt;
V1 → V2 → V3 → V4 → V5&lt;br&gt;
                         ↑&lt;br&gt;
                  Restored fromV2&lt;/p&gt;

&lt;p&gt;So recovery doesn't mean:&lt;/p&gt;

&lt;p&gt;“Delete the past.”&lt;br&gt;
It means:&lt;br&gt;
“Create a new current state based on the past.”&lt;br&gt;
That preserves the complete lineage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building Search Without a Search Library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Search was another interesting challenge.&lt;br&gt;
We wanted users to search versioned structured data without depending on Elasticsearch, Whoosh, or another search package.&lt;br&gt;
So we built an inverted index.&lt;br&gt;
The simplified flow is:&lt;/p&gt;

&lt;p&gt;JSON Records&lt;br&gt;
     ↓&lt;br&gt;
Tokenization&lt;br&gt;
     ↓&lt;br&gt;
Inverted Index&lt;br&gt;
     ↓&lt;br&gt;
Prefix Lookup&lt;br&gt;
     ↓&lt;br&gt;
Field Matching&lt;br&gt;
     ↓&lt;br&gt;
TF-IDF Ranking&lt;br&gt;
     ↓&lt;br&gt;
Relevant Results&lt;/p&gt;

&lt;p&gt;The search system supports:&lt;br&gt;
Exact token matches&lt;br&gt;
Prefix searches&lt;br&gt;
Field matching&lt;br&gt;
Deep nested JSON keys&lt;br&gt;
Relevance ranking&lt;br&gt;
For example, a user could search for:&lt;br&gt;
Java&lt;br&gt;
and discover a value such as:&lt;br&gt;
JavaScript&lt;br&gt;
through prefix matching.&lt;br&gt;
A nested value such as:&lt;br&gt;
{&lt;br&gt;
  "address": {&lt;br&gt;
    "city": "New York"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;can also be discovered through nested-field search.&lt;/p&gt;

&lt;p&gt;This was a particularly valuable exercise because it showed us how much functionality is normally hidden behind a search library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Version Comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another requirement was comparing two versions.&lt;br&gt;
Instead of installing a JSON-diff package, we used standard-library functionality such as difflib together with application-specific comparison logic.&lt;br&gt;
The goal is not simply to say:&lt;br&gt;
V1 != V2&lt;br&gt;
but to expose meaningful changes:&lt;br&gt;
plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic&lt;/li&gt;
&lt;li&gt;Pro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;credit_limit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;500000&lt;/li&gt;
&lt;li&gt;800000
That makes version history useful rather than simply archival.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integrity Verification&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version history is valuable only if users can trust it.&lt;br&gt;
Z-RevixDB therefore uses hashing to maintain integrity information for stored versions.&lt;br&gt;
Python's hashlib provides the required cryptographic hashing primitives.&lt;br&gt;
The conceptual flow is:&lt;/p&gt;

&lt;p&gt;Version Data&lt;br&gt;
     ↓&lt;br&gt;
Hash&lt;br&gt;
     ↓&lt;br&gt;
Store Integrity Information&lt;br&gt;
     ↓&lt;br&gt;
Verify Later&lt;br&gt;
     ↓&lt;br&gt;
Valid / Potentially Modified&lt;/p&gt;

&lt;p&gt;The Integrity Monitor can then scan records and report verification results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit Trail&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Version history tells us how data evolved.&lt;br&gt;
The Audit Trail answers a slightly different question:&lt;br&gt;
What happened in the system?&lt;br&gt;
The system records relevant activities and provides an audit view containing information such as:&lt;br&gt;
Audit Events&lt;br&gt;
Unique Actors&lt;br&gt;
Record Mutations&lt;br&gt;
Security Incidents&lt;br&gt;
Users can filter activity by things such as:&lt;br&gt;
Action&lt;br&gt;
User&lt;br&gt;
Target Record ID&lt;br&gt;
Date Range&lt;br&gt;
and inspect events chronologically.&lt;br&gt;
This makes the platform useful not only for recovery but also for accountability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Standard Library Was Bigger Than We Expected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the biggest surprises during development was realizing how much functionality was already available.&lt;br&gt;
Some of the modules we relied on include:&lt;br&gt;
sqlite3&lt;br&gt;
hashlib&lt;br&gt;
json&lt;br&gt;
http.server&lt;br&gt;
urllib&lt;br&gt;
pathlib&lt;br&gt;
datetime&lt;br&gt;
uuid&lt;br&gt;
threading&lt;br&gt;
difflib&lt;br&gt;
None of these were specifically created for Z-RevixDB.&lt;br&gt;
But together, they provided a surprisingly strong foundation for building a complete application.&lt;br&gt;
The challenge was not finding one magical replacement for every package.&lt;br&gt;
It was learning how to compose smaller primitives into the functionality we needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Was Harder Than the Documentation Made It Look?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The hardest lesson was that replacing a package is rarely a one-to-one substitution.&lt;br&gt;
For example:&lt;br&gt;
Flask → http.server&lt;br&gt;
sounds simple.&lt;br&gt;
But Flask normally provides many conveniences around routing, request handling, responses, error handling, and application structure.&lt;br&gt;
Similarly:&lt;br&gt;
Elasticsearch → custom search&lt;br&gt;
is not simply an import replacement.&lt;br&gt;
You need to think about:&lt;br&gt;
Index construction&lt;br&gt;
Tokenization&lt;br&gt;
Lookup&lt;br&gt;
Prefix matching&lt;br&gt;
Ranking&lt;br&gt;
Field information&lt;br&gt;
Nested data&lt;br&gt;
Result ordering&lt;br&gt;
The package hides complexity.&lt;br&gt;
Removing the package means that complexity becomes your responsibility.&lt;br&gt;
That was the real learning experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Zero Dependency Changed About Our Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Initially, we thought the constraint would mainly affect installation.&lt;br&gt;
It ended up affecting our architecture.&lt;br&gt;
Every time we wanted to use a library, we had to ask:&lt;br&gt;
What problem does it solve?&lt;br&gt;
Then:&lt;br&gt;
What is the minimum functionality we actually need?&lt;br&gt;
And finally:&lt;br&gt;
Can the standard library provide the primitive required to implement it?&lt;br&gt;
This prevented us from blindly adding technology.&lt;br&gt;
We became much more conscious of what each component of the system was actually doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We Learned&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building Z-RevixDB taught us that dependencies aren't necessarily bad.&lt;br&gt;
They save enormous amounts of engineering time.&lt;br&gt;
But using them can also make it easy to forget what happens underneath.&lt;br&gt;
The Zero Dependency constraint forced us to look underneath those abstractions.&lt;br&gt;
We had to think about:&lt;br&gt;
HTTP → Routing → Storage → Indexing → Hashing → Comparison → Versioning → Recovery&lt;br&gt;
instead of simply installing a package for each problem.&lt;br&gt;
And that was probably the most valuable part of the challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thought&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Z-RevixDB started with a simple idea:&lt;br&gt;
Don't just store data. Remember its history.&lt;br&gt;
The Zero Dependency challenge added another question:&lt;br&gt;
How much of that system can we build ourselves using only what our language already provides?&lt;br&gt;
The answer turned out to be much more than we initially expected.&lt;br&gt;
We didn't just remove dependencies.&lt;br&gt;
We discovered what those dependencies were actually doing for us.&lt;br&gt;
&lt;strong&gt;Z-RevixDB&lt;br&gt;
DATA THAT REMEMBERS.&lt;br&gt;
Git remembers code. Z-RevixDB remembers data.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>zerodependency</category>
      <category>database</category>
      <category>python</category>
    </item>
  </channel>
</rss>
