<?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: Swaraj Puppalwar</title>
    <description>The latest articles on DEV Community by Swaraj Puppalwar (@ultrontheai).</description>
    <link>https://dev.to/ultrontheai</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%2F3679100%2F6bde6311-665a-4970-96be-40148aa03e71.png</url>
      <title>DEV Community: Swaraj Puppalwar</title>
      <link>https://dev.to/ultrontheai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ultrontheai"/>
    <language>en</language>
    <item>
      <title>Meet LioranDB: A Document Database Built in Rust</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Tue, 01 Sep 2026 17:25:36 +0000</pubDate>
      <link>https://dev.to/ultrontheai/meet-liorandb-a-document-database-built-in-rust-3e9l</link>
      <guid>https://dev.to/ultrontheai/meet-liorandb-a-document-database-built-in-rust-3e9l</guid>
      <description>&lt;h1&gt;
  
  
  Meet LioranDB: A Document Database Built in Rust
&lt;/h1&gt;

&lt;p&gt;I've been working on &lt;strong&gt;LioranDB&lt;/strong&gt;, a document database built in Rust with a MongoDB-style developer experience.&lt;/p&gt;

&lt;p&gt;And now there's a video about it on YouTube:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=tAAOfV-HyAs" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=tAAOfV-HyAs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LioranDB V2 is currently in &lt;strong&gt;pre-alpha&lt;/strong&gt;, so this isn't a polished "we've finished everything" announcement.&lt;/p&gt;

&lt;p&gt;It's an invitation to developers to experiment with the database, test it, benchmark it, find strange edge cases, and preferably break things before somebody else does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is LioranDB?
&lt;/h2&gt;

&lt;p&gt;LioranDB is a document-oriented database designed around a familiar developer experience while building the underlying database engine in Rust.&lt;/p&gt;

&lt;p&gt;The V2 architecture includes components such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;B+Tree primary storage&lt;/li&gt;
&lt;li&gt;MVCC&lt;/li&gt;
&lt;li&gt;Write-Ahead Logging (WAL)&lt;/li&gt;
&lt;li&gt;Crash recovery&lt;/li&gt;
&lt;li&gt;Secondary indexes&lt;/li&gt;
&lt;li&gt;Full-text indexing&lt;/li&gt;
&lt;li&gt;Page caching&lt;/li&gt;
&lt;li&gt;A query and DBMS layer&lt;/li&gt;
&lt;li&gt;TypeScript/JavaScript driver&lt;/li&gt;
&lt;li&gt;Docker deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conceptually, an application talks to LioranDB like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
LioranDB Driver
     ↓
LioranDB Server
     ↓
Query / DBMS Layer
     ↓
MVCC + Transactions
     ↓
Storage Engine
     ↓
B+Tree / WAL / Cache
     ↓
Disk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Build Another Database?
&lt;/h2&gt;

&lt;p&gt;That's a fair question.&lt;/p&gt;

&lt;p&gt;There are already excellent databases available today.&lt;/p&gt;

&lt;p&gt;LioranDB isn't being built because the world desperately needs another CRUD API.&lt;/p&gt;

&lt;p&gt;The interesting part for me is the infrastructure underneath it.&lt;/p&gt;

&lt;p&gt;How do you make writes durable without destroying throughput?&lt;/p&gt;

&lt;p&gt;How should secondary indexes interact with document storage?&lt;/p&gt;

&lt;p&gt;How do you recover correctly after a crash?&lt;/p&gt;

&lt;p&gt;How do you execute &lt;code&gt;limit()&lt;/code&gt;, sorting and indexed queries without accidentally scanning or hydrating millions of unnecessary documents?&lt;/p&gt;

&lt;p&gt;How do you maintain correctness while optimizing performance?&lt;/p&gt;

&lt;p&gt;Those questions are where building a database gets interesting very quickly.&lt;/p&gt;

&lt;p&gt;Sometimes an optimization gives you a beautiful benchmark.&lt;/p&gt;

&lt;p&gt;Sometimes a tiny change takes performance from &lt;em&gt;nice&lt;/em&gt; to &lt;em&gt;what have I done&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's part of building infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  LioranDB V2 Is Still Pre-Alpha
&lt;/h2&gt;

&lt;p&gt;This part is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LioranDB V2 is not currently presented as production-ready.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pre-alpha is where we're testing the architecture, fixing correctness problems, improving performance and learning from real workloads.&lt;/p&gt;

&lt;p&gt;That also makes this one of the best times for developers interested in databases to experiment with it.&lt;/p&gt;

&lt;p&gt;Don't just test:&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="nf"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try ugly workloads.&lt;/p&gt;

&lt;p&gt;Create indexes.&lt;/p&gt;

&lt;p&gt;Query large collections.&lt;/p&gt;

&lt;p&gt;Restart the database unexpectedly.&lt;/p&gt;

&lt;p&gt;Run concurrent reads and writes.&lt;/p&gt;

&lt;p&gt;Try unusual filters.&lt;/p&gt;

&lt;p&gt;Push pagination.&lt;/p&gt;

&lt;p&gt;Try to make something behave incorrectly.&lt;/p&gt;

&lt;p&gt;If you find something broken, that's useful information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Performance Target
&lt;/h2&gt;

&lt;p&gt;Our pre-alpha development target has been approximately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 writes/sec
+
35,000 reads/sec
------------------
≈ 45,000 operations/sec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are &lt;strong&gt;development benchmark figures, not an SLA or guaranteed production performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Actual throughput depends on hardware, dataset size, document structure, indexes, query patterns, concurrency and many other factors.&lt;/p&gt;

&lt;p&gt;Performance numbers without workload context are mostly decorative numbers wearing suits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch the Video
&lt;/h2&gt;

&lt;p&gt;If you'd rather see LioranDB than read another wall of database text, I've published a video on YouTube:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=tAAOfV-HyAs" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=tAAOfV-HyAs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'll continue publishing more about the internals of LioranDB, including the storage engine, indexing, WAL, MVCC, query execution, performance work and some of the bugs we've encountered while building it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try LioranDB
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LioranDB V2 is still evolving, so feedback at this stage genuinely matters.&lt;/p&gt;

&lt;p&gt;If you're a backend, Rust, database or infrastructure developer, try it.&lt;/p&gt;

&lt;p&gt;Benchmark it.&lt;/p&gt;

&lt;p&gt;Inspect how it behaves.&lt;/p&gt;

&lt;p&gt;And if you can break it, &lt;strong&gt;please tell me how you did it.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>liorandb</category>
      <category>database</category>
      <category>nosql</category>
      <category>developers</category>
    </item>
    <item>
      <title>LioranDB Managed Hosting Is Now Open: ₹5,000/Month for Early-Stage Startups</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Tue, 01 Sep 2026 17:20:57 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-managed-hosting-is-now-open-5000month-for-early-stage-startups-29ha</link>
      <guid>https://dev.to/ultrontheai/liorandb-managed-hosting-is-now-open-5000month-for-early-stage-startups-29ha</guid>
      <description>&lt;p&gt;LioranDB V2 is currently in pre-alpha, and we're now opening &lt;strong&gt;managed LioranDB deployments&lt;/strong&gt; for selected early-stage startups and developers.&lt;/p&gt;

&lt;p&gt;Until now, the focus has primarily been on building and testing the database itself: the Rust storage engine, B+Tree primary storage, MVCC, WAL and crash recovery, secondary indexes, full-text search, and the developer APIs around them.&lt;/p&gt;

&lt;p&gt;Now I want to start working directly with real applications.&lt;/p&gt;

&lt;p&gt;So instead of simply giving developers a Docker image and saying &lt;em&gt;good luck&lt;/em&gt;, we're introducing a small managed offering with direct founder support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Pricing Options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Fixed Plan: ₹5,000/month
&lt;/h3&gt;

&lt;p&gt;This is designed primarily for early-stage products that don't need huge infrastructure yet.&lt;/p&gt;

&lt;p&gt;The plan includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Up to 1 million documents&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Daily database backups&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Managed LioranDB deployment&lt;/li&gt;
&lt;li&gt;Infrastructure monitoring and maintenance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Direct founder support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Basic feature requests based on your application's requirements&lt;/li&gt;
&lt;li&gt;Help with database integration and deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LioranDB's current development testing has demonstrated workloads around &lt;strong&gt;10K writes/sec + 35K reads/sec&lt;/strong&gt;, or roughly &lt;strong&gt;45K operations/sec&lt;/strong&gt; under tested configurations.&lt;/p&gt;

&lt;p&gt;These numbers should be treated as &lt;strong&gt;development benchmark figures, not guaranteed production throughput or an SLA&lt;/strong&gt;. Actual performance depends heavily on hardware, indexes, query patterns, document sizes, concurrency, and workload.&lt;/p&gt;

&lt;p&gt;LioranDB V2 itself is also currently &lt;strong&gt;pre-alpha&lt;/strong&gt;, so this offering is aimed at teams comfortable adopting early infrastructure and working directly with its developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Custom Plan
&lt;/h3&gt;

&lt;p&gt;Need more than 1 million documents?&lt;/p&gt;

&lt;p&gt;Need different CPU, memory, storage, backup policies, or workload requirements?&lt;/p&gt;

&lt;p&gt;That's where the &lt;strong&gt;custom plan&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Instead of forcing every application into the same infrastructure configuration, we'll review your application's expected workload and determine an appropriate deployment and monthly price.&lt;/p&gt;

&lt;p&gt;This is particularly useful for SaaS platforms, CRM systems, backend services, AI applications, and other products with unusual or rapidly growing database workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do You Get a Managed LioranDB Database?
&lt;/h2&gt;

&lt;p&gt;We're not making managed deployments instantly purchasable yet.&lt;/p&gt;

&lt;p&gt;There is an application process.&lt;/p&gt;

&lt;p&gt;Visit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app.liorandb.com&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an account and submit an application describing your product, expected workload, and database requirements.&lt;/p&gt;

&lt;p&gt;We'll review the application.&lt;/p&gt;

&lt;p&gt;If it's approved, we'll provision your LioranDB database and provide the information you need to connect your application.&lt;/p&gt;

&lt;p&gt;Billing is monthly.&lt;/p&gt;

&lt;p&gt;The process looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create Account
      ↓
Submit Application
      ↓
Application Review
      ↓
Approved
      ↓
Database Provisioned
      ↓
Connect Your Application
      ↓
Monthly Billing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why an Application Process?
&lt;/h2&gt;

&lt;p&gt;Because LioranDB V2 is still pre-alpha.&lt;/p&gt;

&lt;p&gt;I'd rather onboard a smaller number of applications and understand exactly how they're using the database than throw open a giant &lt;strong&gt;"Buy Now"&lt;/strong&gt; button and pretend the product has already reached cloud-database maturity.&lt;/p&gt;

&lt;p&gt;Working with early users also gives us something benchmarks can't provide: &lt;strong&gt;real workloads&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different applications create very different database pressure.&lt;/p&gt;

&lt;p&gt;A CRM might perform huge numbers of indexed lookups.&lt;/p&gt;

&lt;p&gt;A SaaS product might have strongly tenant-oriented access patterns.&lt;/p&gt;

&lt;p&gt;An API might perform thousands of tiny reads.&lt;/p&gt;

&lt;p&gt;Another application might continuously ingest data.&lt;/p&gt;

&lt;p&gt;Those workloads expose problems synthetic benchmarks simply won't.&lt;/p&gt;

&lt;p&gt;And because managed customers have direct founder support, if something strange happens, you're talking directly to the person building the database rather than bouncing through three support tiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is LioranDB?
&lt;/h2&gt;

&lt;p&gt;LioranDB V2 is a document database developed in Rust with a MongoDB-style developer experience.&lt;/p&gt;

&lt;p&gt;Its current architecture includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
     ↓
LioranDB Query Layer
     ↓
Transactions + MVCC
     ↓
B+Tree Primary Storage
     ↓
WAL + Checkpoints
     ↓
Page Cache
     ↓
Persistent Storage

     + Secondary LSM Indexes
     + Inverted Text Index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;V2 pre-alpha launched on &lt;strong&gt;August 16, 2026&lt;/strong&gt;, and development is currently moving toward the Alpha release planned for &lt;strong&gt;October 23, 2026&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The database is still under active development and &lt;strong&gt;is not currently presented as production-ready&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's also why I'm particularly interested in working with developers who are willing to test it, push it, report weird behavior, and tell me where the developer experience sucks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interested?
&lt;/h2&gt;

&lt;p&gt;You can learn about LioranDB on &lt;strong&gt;liorandb.com&lt;/strong&gt;, or apply for a managed deployment through &lt;strong&gt;app.liorandb.com&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're building an early-stage SaaS, CRM, API, internal tool, or another backend-heavy product and want to experiment with LioranDB, I'd particularly like to hear about your workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And yes, trying to break the database is still encouraged.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>liorandb</category>
      <category>nosql</category>
      <category>database</category>
      <category>developers</category>
    </item>
    <item>
      <title>LioranDB V2 Is in Pre-Alpha. Please Try to Break It.</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 29 Aug 2026 19:39:12 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-v2-is-in-pre-alpha-please-try-to-break-it-j46</link>
      <guid>https://dev.to/ultrontheai/liorandb-v2-is-in-pre-alpha-please-try-to-break-it-j46</guid>
      <description>&lt;p&gt;LioranDB V2 is now publicly available in &lt;strong&gt;pre-alpha&lt;/strong&gt;, and I want developers to do something slightly unusual:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try to break it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not just install it, run &lt;code&gt;insertOne()&lt;/code&gt;, see that it works, and close the terminal.&lt;/p&gt;

&lt;p&gt;Push it.&lt;/p&gt;

&lt;p&gt;Give it weird queries. Throw large datasets at it. Create indexes. Delete things. Restart the server. Send concurrent requests. Test edge cases. Try workflows I probably didn't think about.&lt;/p&gt;

&lt;p&gt;If something behaves strangely, becomes painfully slow, crashes, returns an unexpected result, or simply feels bad to use, I want to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is LioranDB?
&lt;/h2&gt;

&lt;p&gt;LioranDB is a developer-first document database being developed in India.&lt;/p&gt;

&lt;p&gt;V2 is written in &lt;strong&gt;Rust&lt;/strong&gt; and currently includes things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;B+ Tree primary storage&lt;/li&gt;
&lt;li&gt;MVCC&lt;/li&gt;
&lt;li&gt;Write-Ahead Logging&lt;/li&gt;
&lt;li&gt;Checkpoints and crash recovery&lt;/li&gt;
&lt;li&gt;Secondary indexes&lt;/li&gt;
&lt;li&gt;Full-text indexing&lt;/li&gt;
&lt;li&gt;Docker deployment&lt;/li&gt;
&lt;li&gt;TypeScript/JavaScript driver&lt;/li&gt;
&lt;li&gt;MongoDB-style document APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to pretend that a pre-alpha database is already production-ready.&lt;/p&gt;

&lt;p&gt;The goal is to find everything that's wrong with it &lt;strong&gt;before&lt;/strong&gt; it gets there.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, I'm Looking for Feedback
&lt;/h2&gt;

&lt;p&gt;I'm especially interested in hearing about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐛 Bugs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anything that crashes, hangs, produces incorrect results, corrupts state, or behaves differently from what you'd expect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚡ Performance problems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Slow queries, unexpected latency, bad scaling with larger collections, inefficient indexes, memory problems, or operations that become suspiciously expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Edge cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Strange documents. Strange queries. Strange sequences of operations.&lt;/p&gt;

&lt;p&gt;Basically, be creative.&lt;/p&gt;

&lt;p&gt;Databases tend to behave nicely until somebody does something the database author never imagined.&lt;/p&gt;

&lt;p&gt;Be that somebody.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧑‍💻 Developer experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd also love feedback about the API itself.&lt;/p&gt;

&lt;p&gt;Is something confusing?&lt;/p&gt;

&lt;p&gt;Does an error message suck?&lt;/p&gt;

&lt;p&gt;Is an operation unnecessarily complicated?&lt;/p&gt;

&lt;p&gt;Did you have to read the documentation three times to understand something?&lt;/p&gt;

&lt;p&gt;That's a bug too, just wearing nicer clothes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Test It
&lt;/h2&gt;

&lt;p&gt;Start here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LioranDB:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The documentation contains the setup instructions and APIs needed to start experimenting with LioranDB.&lt;/p&gt;

&lt;p&gt;You don't need to build a serious application.&lt;/p&gt;

&lt;p&gt;Create a test project, generate some data, connect the driver, and start attacking it.&lt;/p&gt;

&lt;p&gt;Try things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;thousands or millions of documents&lt;/li&gt;
&lt;li&gt;concurrent reads and writes&lt;/li&gt;
&lt;li&gt;secondary indexes&lt;/li&gt;
&lt;li&gt;text search&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;large &lt;code&gt;limit()&lt;/code&gt; values&lt;/li&gt;
&lt;li&gt;unusual filters&lt;/li&gt;
&lt;li&gt;sorting&lt;/li&gt;
&lt;li&gt;aggregations&lt;/li&gt;
&lt;li&gt;repeated updates and deletes&lt;/li&gt;
&lt;li&gt;restarting LioranDB during workloads&lt;/li&gt;
&lt;li&gt;crash/recovery scenarios&lt;/li&gt;
&lt;li&gt;combinations of operations that look suspicious&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you manage to make LioranDB unhappy, congratulations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's exactly what I'm looking for.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Found Something?
&lt;/h2&gt;

&lt;p&gt;Send me what happened at:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="mailto:feedback@liorandb.com"&gt;feedback@liorandb.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If possible, include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what you were trying to do&lt;/li&gt;
&lt;li&gt;the query/code you ran&lt;/li&gt;
&lt;li&gt;what you expected&lt;/li&gt;
&lt;li&gt;what actually happened&lt;/li&gt;
&lt;li&gt;dataset size&lt;/li&gt;
&lt;li&gt;logs or error messages&lt;/li&gt;
&lt;li&gt;your OS/environment&lt;/li&gt;
&lt;li&gt;reproduction steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you're unsure whether something is technically a bug, send it.&lt;/p&gt;

&lt;p&gt;Performance observations, confusing APIs, documentation problems, missing features, architectural criticism, and general feedback are all useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm Doing This
&lt;/h2&gt;

&lt;p&gt;A database isn't validated because its benchmark graph looks pretty.&lt;/p&gt;

&lt;p&gt;It's validated when people outside the project start doing things the original developer didn't anticipate.&lt;/p&gt;

&lt;p&gt;LioranDB V2 is still pre-alpha.&lt;/p&gt;

&lt;p&gt;There are going to be bugs.&lt;/p&gt;

&lt;p&gt;There are going to be slow paths.&lt;/p&gt;

&lt;p&gt;There are probably wonderfully cursed combinations of operations waiting somewhere in the engine.&lt;/p&gt;

&lt;p&gt;I'd rather developers discover them now than users discover them later.&lt;/p&gt;

&lt;p&gt;So install LioranDB.&lt;/p&gt;

&lt;p&gt;Build something stupid with it.&lt;/p&gt;

&lt;p&gt;Stress it.&lt;/p&gt;

&lt;p&gt;Abuse the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And please, try to break my database.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback: &lt;strong&gt;&lt;a href="mailto:feedback@liorandb.com"&gt;feedback@liorandb.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>liorandb</category>
      <category>nosql</category>
      <category>database</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Swaraj's High Rise in Computers! | Nagpur Post | 23 May 2023</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Mon, 24 Aug 2026 15:14:50 +0000</pubDate>
      <link>https://dev.to/ultrontheai/swarajs-high-rise-in-computers-nagpur-post-23-may-2023-4cj2</link>
      <guid>https://dev.to/ultrontheai/swarajs-high-rise-in-computers-nagpur-post-23-may-2023-4cj2</guid>
      <description>&lt;p&gt;On Tuesday, 23 May 2023, Nagpur Post published an English feature about my early journey into computers and programming.&lt;/p&gt;

&lt;p&gt;The article was titled “Swaraj's high rise in computers!” with the subheading “Developed many computer programs at an early age.”&lt;/p&gt;

&lt;p&gt;I was 15 years old when the article was published.&lt;/p&gt;

&lt;p&gt;I had started programming at the age of 11 and was primarily self-taught, learning through books, online tutorials, platforms such as Udemy and YouTube, and, most importantly, building projects.&lt;/p&gt;

&lt;p&gt;By that point, I had experimented with software, Android applications, websites and games.&lt;/p&gt;

&lt;p&gt;Some of my early projects included Productive Pay, a productivity tool for Python developers, a calculation-speed improvement tool for mathematics practice, and applications built while experimenting with multiple programming languages.&lt;/p&gt;

&lt;p&gt;My early technology stack included Python, Java, C/C++, HTML, CSS, JavaScript and Node.js.&lt;/p&gt;

&lt;p&gt;The newspaper also covered some of my participation and achievements in computer science and academic competitions, including cyber, computer and mathematics olympiads and the National Children's Science Congress.&lt;/p&gt;

&lt;p&gt;Reading the article again years later feels almost like opening an old Git commit.&lt;/p&gt;

&lt;p&gt;The codebase has changed considerably.&lt;/p&gt;

&lt;p&gt;What started as curiosity about programming eventually grew into an interest in full-stack development, backend engineering, databases and developer infrastructure.&lt;/p&gt;

&lt;p&gt;Today, I am building LioranDB and working toward a much larger goal: building developer infrastructure from India.&lt;/p&gt;

&lt;p&gt;I am preserving this article here because it captures one of the earliest public records of that journey, from a time when I was simply a school student fascinated by what could be built with a computer and some code.&lt;/p&gt;

&lt;p&gt;Publication: Nagpur Post&lt;br&gt;
Location: Nagpur&lt;br&gt;
Date: Tuesday, 23 May 2023&lt;br&gt;
Original Headline: Swaraj's high rise in computers!&lt;br&gt;
Subheading: Developed many computer programs at an early age&lt;/p&gt;

</description>
      <category>swarajpuppalwar</category>
      <category>nagpurpost</category>
      <category>news</category>
    </item>
    <item>
      <title>स्वराजची संगणक क्षेत्रात उंच भरारी | Navarashtra, Chandrapur | 23 May 2023</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Mon, 24 Aug 2026 15:14:10 +0000</pubDate>
      <link>https://dev.to/ultrontheai/svraajcii-sngnnk-kssetraat-unc-bhraarii-navarashtra-chandrapur-23-may-2023-4jao</link>
      <guid>https://dev.to/ultrontheai/svraajcii-sngnnk-kssetraat-unc-bhraarii-navarashtra-chandrapur-23-may-2023-4jao</guid>
      <description>&lt;p&gt;On 23 May 2023, Navarashtra featured my early journey in computer science and programming in its Chandrapur edition.&lt;/p&gt;

&lt;p&gt;The article was published under the Marathi headline “स्वराजची संगणक क्षेत्रात उंच भरारी” on Page 4.&lt;/p&gt;

&lt;p&gt;I was 15 years old at the time.&lt;/p&gt;

&lt;p&gt;My journey into programming had started several years earlier, when I began learning to code at the age of 11. Instead of limiting that learning to tutorials, I became interested in actually building things.&lt;/p&gt;

&lt;p&gt;Over the following years, I experimented with software, Android applications, websites, games and programming projects while continuing to learn different technologies.&lt;/p&gt;

&lt;p&gt;The Navarashtra article documented this early phase of my journey and highlighted both my programming work and participation in technology and academic competitions.&lt;/p&gt;

&lt;p&gt;Some of the technologies I explored during those years included Python, Java, C/C++, HTML, CSS, JavaScript and Node.js.&lt;/p&gt;

&lt;p&gt;What I find interesting about looking at this article years later is how much the scale of the problems I want to solve has changed.&lt;/p&gt;

&lt;p&gt;The 15-year-old version of me was excited about making applications and experimenting with code.&lt;/p&gt;

&lt;p&gt;Today, I spend much of my time thinking about storage engines, databases, Rust, backend architecture and developer infrastructure.&lt;/p&gt;

&lt;p&gt;Those are very different engineering problems, but they came from the same curiosity.&lt;/p&gt;

&lt;p&gt;This clipping is therefore more than a newspaper mention for me. It is a snapshot of where the journey was in May 2023, long before I knew where that curiosity would eventually lead.&lt;/p&gt;

&lt;p&gt;Publication: Navarashtra&lt;br&gt;
Edition: Chandrapur&lt;br&gt;
Date: 23 May 2023&lt;br&gt;
Page: 4&lt;br&gt;
Original Marathi Headline: स्वराजची संगणक क्षेत्रात उंच भरारी&lt;/p&gt;

</description>
      <category>swarajpuppalwar</category>
      <category>navarashtra</category>
      <category>news</category>
    </item>
    <item>
      <title>‘स्वराज’ची संगणकात गगनभरारी | Tarun Bharat, Purva Vidarbha | 29 May 2023</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Mon, 24 Aug 2026 15:13:30 +0000</pubDate>
      <link>https://dev.to/ultrontheai/svraajcii-sngnnkaat-ggnbhraarii-tarun-bharat-purva-vidarbha-29-may-2023-1m8d</link>
      <guid>https://dev.to/ultrontheai/svraajcii-sngnnkaat-ggnbhraarii-tarun-bharat-purva-vidarbha-29-may-2023-1m8d</guid>
      <description>&lt;p&gt;On 29 May 2023, Tarun Bharat featured my journey in technology and programming in its Purva Vidarbha edition.&lt;/p&gt;

&lt;p&gt;The Marathi article, titled “‘स्वराज’ची संगणकात गगनभरारी”, appeared on Page 2 of the newspaper.&lt;/p&gt;

&lt;p&gt;At the time, I was 15 years old and had already spent several years exploring programming and computer science. I started programming at the age of 11, largely learning through experimentation, books, online resources and building projects of my own.&lt;/p&gt;

&lt;p&gt;The article covered my early journey in software development, including my work with programming languages and technologies such as Python, Java, C/C++, HTML, CSS, JavaScript and Node.js.&lt;/p&gt;

&lt;p&gt;It also highlighted some of the projects I had built while learning programming, along with my participation and achievements in computer science, cyber and mathematics competitions.&lt;/p&gt;

&lt;p&gt;Looking back from 2026, this newspaper clipping represents a very different stage of my journey.&lt;/p&gt;

&lt;p&gt;Back then, I was a school student experimenting with software because I genuinely enjoyed understanding how computers worked.&lt;/p&gt;

&lt;p&gt;Today, that curiosity has evolved into working on databases, backend systems and developer infrastructure, including building LioranDB.&lt;/p&gt;

&lt;p&gt;The technology has changed. The projects have become much larger. But the habit that started everything remains the same: learn something, build something, break it, understand it, and build again.&lt;/p&gt;

&lt;p&gt;Publication: Tarun Bharat&lt;br&gt;
Edition: Purva Vidarbha&lt;br&gt;
Date: 29 May 2023&lt;br&gt;
Page: 2&lt;br&gt;
Original Marathi Headline: ‘स्वराज’ची संगणकात गगनभरारी&lt;/p&gt;

</description>
      <category>swarajpuppalwar</category>
      <category>tarunbharat</category>
      <category>news</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #12: Production Patterns, Error Handling and What Comes Next</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:16:34 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-12-production-patterns-error-handling-and-what-comes-next-2aok</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-12-production-patterns-error-handling-and-what-comes-next-2aok</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #12: Production Patterns, Error Handling and What Comes Next
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We started this series with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eleven articles later, we've covered application queries, indexes, authentication, operations, backups, the CLI and managed deployment.&lt;/p&gt;

&lt;p&gt;Let's finish with the things that matter when your application stops being a demo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understand driver errors
&lt;/h2&gt;

&lt;p&gt;The LioranDB TypeScript driver exports a structured error hierarchy.&lt;/p&gt;

&lt;p&gt;General errors include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LioranDriverError
ApiError
AuthError
NetworkError
TimeoutError
ConfigurationError
SerializationError
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication-related errors include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AuthenticationError
AuthorizationError
PasswordChangeRequiredError
SessionExpiredError
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lifecycle errors include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClientClosedError
CursorClosedError
CursorInitializedError
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server-side conditions include errors such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ConflictError
DuplicateKeyError
NotFoundError
ServerNotReadyError
ServerOverloadedError
ServerUnavailableError
ValidationError
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use &lt;code&gt;instanceof&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Don't parse human-readable error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;DuplicateKeyError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TimeoutError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@liorandb/driver&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;DuplicateKeyError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle duplicate data.&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;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;TimeoutError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Apply your timeout/retry policy.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;throw&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The driver also exports error and warning code constants for applications that need structured classification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add diagnostics
&lt;/h2&gt;

&lt;p&gt;Attach your application's trace identifier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setDiagnosticHeaders&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-trace-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;traceId&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;Observe operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setResponseObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;durationMS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;durationMS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;requestId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requestId&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;And surface slow operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&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;LioranDBClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;slowRequestThresholdMS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;onWarning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;warning&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Production checklist
&lt;/h2&gt;

&lt;p&gt;Before calling a deployment production-ready:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL-encode credentials inside connection strings.&lt;/li&gt;
&lt;li&gt;Rotate bootstrap credentials immediately.&lt;/li&gt;
&lt;li&gt;Use application-specific users and roles.&lt;/li&gt;
&lt;li&gt;Prefer least-privilege permissions.&lt;/li&gt;
&lt;li&gt;Use typed collections.&lt;/li&gt;
&lt;li&gt;Use idempotency keys where retry safety matters.&lt;/li&gt;
&lt;li&gt;Configure appropriate request timeouts.&lt;/li&gt;
&lt;li&gt;Poll backup and restore jobs until terminal state.&lt;/li&gt;
&lt;li&gt;Verify backups.&lt;/li&gt;
&lt;li&gt;Monitor health, readiness and metrics.&lt;/li&gt;
&lt;li&gt;Keep database ports private.&lt;/li&gt;
&lt;li&gt;Put TLS at the public edge.&lt;/li&gt;
&lt;li&gt;Close clients and cursors cleanly.&lt;/li&gt;
&lt;li&gt;Handle structured driver errors rather than parsing strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Remember: this is pre-alpha
&lt;/h2&gt;

&lt;p&gt;LioranDB V2 launched its pre-alpha on &lt;strong&gt;16 August 2026&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That word matters.&lt;/p&gt;

&lt;p&gt;Pre-alpha is where APIs can evolve, edge cases get discovered and real workloads expose assumptions that benchmarks don't.&lt;/p&gt;

&lt;p&gt;If you're experimenting with it today, feedback is extremely valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next?
&lt;/h2&gt;

&lt;p&gt;The current target for the LioranDB V2 alpha is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;23 October 2026&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Work toward alpha includes areas such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;production hardening&lt;/li&gt;
&lt;li&gt;larger dataset testing&lt;/li&gt;
&lt;li&gt;richer aggregation capabilities&lt;/li&gt;
&lt;li&gt;clustering improvements&lt;/li&gt;
&lt;li&gt;deployment tooling&lt;/li&gt;
&lt;li&gt;managed infrastructure&lt;/li&gt;
&lt;li&gt;developer experience improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The direction remains the same:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build developer infrastructure from India that developers can actually use.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start building
&lt;/h2&gt;

&lt;p&gt;Install the driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @liorandb/driver@2.0.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @liorandb/cli@1.0.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull liorandb/liorandb:pre-alpha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LioranDB:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Driver:&lt;/strong&gt; &lt;code&gt;@liorandb/driver@2.0.5&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;CLI:&lt;/strong&gt; &lt;code&gt;@liorandb/cli@1.0.5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;LioranDB is created by &lt;strong&gt;Swaraj Puppalwar&lt;/strong&gt;, Founder &amp;amp; CTO at Lioran Developer Solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/UltronTheAI" rel="noopener noreferrer"&gt;https://github.com/UltronTheAI&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Lioran Developer Solutions:&lt;/strong&gt; &lt;a href="https://lioransolutions.com" rel="noopener noreferrer"&gt;https://lioransolutions.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 11 → Docker Compose, Caddy &amp;amp; TLS&lt;/p&gt;

&lt;p&gt;That's the end of the LioranDB TypeScript Series.&lt;/p&gt;

&lt;p&gt;Now comes the fun part:&lt;/p&gt;

&lt;p&gt;Build something with it, stress it, benchmark it, find the weird edge cases and tell us what you discover.&lt;/p&gt;

&lt;p&gt;Pre-alpha gets better when developers actually try to break it. 💗&lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #11: Deploy LioranDB with Docker Compose, Caddy and TLS</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:14:45 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-11-deploy-liorandb-with-docker-compose-caddy-and-tls-4egh</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-11-deploy-liorandb-with-docker-compose-caddy-and-tls-4egh</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #11: Deploy LioranDB with Docker Compose, Caddy and TLS
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Running LioranDB locally is easy.&lt;/p&gt;

&lt;p&gt;Exposing a database server to the internet deserves considerably more care.&lt;/p&gt;

&lt;p&gt;Let's build a cleaner managed deployment.&lt;/p&gt;

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

&lt;p&gt;Instead of publishing every LioranDB port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet
   ↓
HTTPS / TLS
   ↓
Caddy
   ↓
Docker network
   ↓
LioranDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the reverse proxy should be publicly reachable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Caddy configuration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acme.db.example.com {
  reverse_proxy liorandb:27018
}

acme.grpc.example.com {
  reverse_proxy h2c://liorandb:27019
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caddy handles the public TLS edge while LioranDB remains inside the Docker network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Compose
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;liorandb&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;liorandb/liorandb:pre-alpha&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;liorandb-acme&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;

    &lt;span class="na"&gt;cpus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.0&lt;/span&gt;
    &lt;span class="na"&gt;mem_limit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.5g&lt;/span&gt;

    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;LIORANDB_TLS_MODE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;insecure&lt;/span&gt;
      &lt;span class="na"&gt;LIORANDB_GRPC_BIND_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0:27019&lt;/span&gt;
      &lt;span class="na"&gt;LIORANDB_METRICS_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0:27201&lt;/span&gt;

      &lt;span class="na"&gt;LIORANDB_ADVERTISED_HTTP_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;acme.db.example.com:443&lt;/span&gt;
      &lt;span class="na"&gt;LIORANDB_ADVERTISED_GRPC_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;acme.grpc.example.com:443&lt;/span&gt;

      &lt;span class="na"&gt;LIORANDB_BOOTSTRAP_PASSWORD_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/run/liorandb/bootstrap-password.txt&lt;/span&gt;

    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27018"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27019"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27201"&lt;/span&gt;

    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;liorandb-data:/var/lib/liorandb/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./bootstrap-password.txt:/run/liorandb/bootstrap-password.txt:ro&lt;/span&gt;

    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;public-edge&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;metrics-private&lt;/span&gt;

  &lt;span class="na"&gt;caddy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;caddy:2&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;

    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&lt;/span&gt;

    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./Caddyfile:/etc/caddy/Caddyfile:ro&lt;/span&gt;

    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;public-edge&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;liorandb-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;public-edge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;metrics-private&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;internal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notice what's missing
&lt;/h2&gt;

&lt;p&gt;There is no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27018:27018"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27019:27019"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27201:27201"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;on the LioranDB service.&lt;/p&gt;

&lt;p&gt;That's deliberate.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expose&lt;/code&gt; makes the ports available to services on the Docker network without publishing them directly on the host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Firewall
&lt;/h2&gt;

&lt;p&gt;For a typical Ubuntu deployment, the public firewall should only need the services you intentionally expose, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;22   SSH
80   HTTP
443  HTTPS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't casually expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;27018
27019
27201
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to the public internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bootstrap password file
&lt;/h2&gt;

&lt;p&gt;Generate a strong secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store it in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bootstrap-password.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restrict access:&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="nb"&gt;chmod &lt;/span&gt;600 bootstrap-password.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container receives it as a read-only mounted file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment flow
&lt;/h2&gt;

&lt;p&gt;Validate your Compose configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify health/readiness and advertised endpoints before connecting application traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Application connection
&lt;/h2&gt;

&lt;p&gt;Your application can then connect through the public TLS endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;liorandb://admin:&amp;lt;encoded-password&amp;gt;@acme.db.example.com:443/default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to URL-encode the password.&lt;/p&gt;

&lt;h2&gt;
  
  
  The important boundary
&lt;/h2&gt;

&lt;p&gt;The database is not your public web server.&lt;/p&gt;

&lt;p&gt;Treat the reverse proxy as the edge and keep the database itself on the private network.&lt;/p&gt;

&lt;p&gt;That one architectural decision removes an impressive collection of future headaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Managed Deployment Guide:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.liorandb.com/docs/deployment/managed" rel="noopener noreferrer"&gt;https://docs.liorandb.com/docs/deployment/managed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 10 → Official CLI&lt;br&gt;
&lt;strong&gt;Next:&lt;/strong&gt; Part 12 → Production Patterns, Diagnostics &amp;amp; What's Next&lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #10: Mastering the Official LioranDB CLI</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:13:15 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-10-mastering-the-official-liorandb-cli-4i24</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-10-mastering-the-official-liorandb-cli-4i24</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #10: Mastering the Official LioranDB CLI
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not everything needs a dashboard.&lt;/p&gt;

&lt;p&gt;Sometimes you just want a terminal and a database that listens.&lt;/p&gt;

&lt;p&gt;Meet the official LioranDB CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @liorandb/cli@1.0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Initialize
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure a connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb &lt;span class="nb"&gt;set &lt;/span&gt;url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"liorandb://admin:YOUR_PASSWORD@127.0.0.1:27018/default"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authenticate:&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="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LIORANDB_PASSWORD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; |
liorandb login admin &lt;span class="nt"&gt;--password-stdin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Select a database
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb db use default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb collection create products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Insert from stdin
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'{"sku":"bk-001","title":"Blue Notebook","active":true}'&lt;/span&gt; |
liorandb insert-one products &lt;span class="nt"&gt;--stdin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb count products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then jump into the interactive shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;liorandb shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Profiles
&lt;/h2&gt;

&lt;p&gt;The CLI supports local profiles, which makes switching environments much less painful.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local
staging
production
client-a
client-b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of repeatedly pasting connection information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Output formats
&lt;/h2&gt;

&lt;p&gt;Automation doesn't want pretty tables.&lt;/p&gt;

&lt;p&gt;Humans often do.&lt;/p&gt;

&lt;p&gt;The CLI supports output modes including:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;table
json
ndjson
quiet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Global flags include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--profile
--url
--output
--json
--quiet
--no-color
--debug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What can the CLI control?
&lt;/h2&gt;

&lt;p&gt;Quite a lot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;db
collection
find
find-one
insert-one
update-one
delete-many
aggregate
count
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Indexes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index list
index create
index create-text
index drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;login
logout
whoami
sessions
change-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Administration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user
role
settings
cors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Operations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;status
health
doctor
metrics
cluster
backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Safety
&lt;/h2&gt;

&lt;p&gt;Destructive commands should be difficult to trigger accidentally.&lt;/p&gt;

&lt;p&gt;Operations such as drops, broad deletions and backup restore/delete flows use confirmation mechanisms unless explicitly overridden where supported.&lt;/p&gt;

&lt;p&gt;That's intentional.&lt;/p&gt;

&lt;p&gt;A CLI should help you operate the database, not speedrun deleting Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local state
&lt;/h2&gt;

&lt;p&gt;CLI state is stored under:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You can override the location with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Passwords are not persisted as ordinary stored profile values.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI + Driver
&lt;/h2&gt;

&lt;p&gt;The CLI and TypeScript driver aren't competing interfaces.&lt;/p&gt;

&lt;p&gt;A common setup is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application code
    → @liorandb/driver

Developers / CI / Operations
    → @liorandb/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use each where it fits best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CLI Documentation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.liorandb.com/docs/cli/overview" rel="noopener noreferrer"&gt;https://docs.liorandb.com/docs/cli/overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 9 → Operations &amp;amp; Backups&lt;br&gt;
&lt;strong&gt;Next:&lt;/strong&gt; Part 11 → Docker Compose, Caddy &amp;amp; TLS&lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #9: Backups, Cluster Health and Operational APIs</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:11:45 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-9-backups-cluster-health-and-operational-apis-5c6p</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-9-backups-cluster-health-and-operational-apis-5c6p</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #9: Backups, Cluster Health and Operational APIs
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So far we've mostly treated LioranDB as an application database.&lt;/p&gt;

&lt;p&gt;But the driver also exposes the operational side of the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cluster state
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;summary&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&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;nodes&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nodes&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;partitions&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partitions&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;health&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;health&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;readiness&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readiness&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes operational tooling possible without maintaining a completely separate client stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Administrative operations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkpoint&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compact&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are administrative operations, so treat them accordingly.&lt;/p&gt;

&lt;p&gt;Don't put &lt;code&gt;compact()&lt;/code&gt; inside the request handler for &lt;code&gt;/api/users&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I shouldn't need to say that, but somewhere a server just became nervous. 🤕&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a backup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;backup&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production-before-migration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;local_node&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;Cluster-scoped backups can also be requested where supported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backup jobs are asynchronous
&lt;/h2&gt;

&lt;p&gt;Creating a backup doesn't mean the backup has already completed.&lt;/p&gt;

&lt;p&gt;Retrieve its state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;job&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backup_id&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production code should poll the job until it reaches its terminal state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify backups
&lt;/h2&gt;

&lt;p&gt;A backup you have never verified is a very optimistic file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backup_id&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Restore
&lt;/h2&gt;

&lt;p&gt;Restores intentionally require explicit confirmation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restore&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backup_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;confirmation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="s2"&gt;`RESTORE &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;backup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backup_id&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="na"&gt;disable_safety_backup&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="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;Then monitor the restore job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;restoreJob&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRestoreJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;job_id&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Runtime settings
&lt;/h2&gt;

&lt;p&gt;The driver also exposes server settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCors&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPerformance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLimits&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBackups&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Administrative applications can update the corresponding configuration through the settings service.&lt;/p&gt;

&lt;p&gt;That includes areas such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CORS&lt;/li&gt;
&lt;li&gt;performance controls&lt;/li&gt;
&lt;li&gt;server limits&lt;/li&gt;
&lt;li&gt;backup configuration&lt;/li&gt;
&lt;li&gt;backup retention and schedules&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why expose operations through TypeScript?
&lt;/h2&gt;

&lt;p&gt;Because infrastructure increasingly becomes software.&lt;/p&gt;

&lt;p&gt;Your internal control plane, managed-database dashboard, backup worker and deployment automation can all talk to the same database through a typed SDK.&lt;/p&gt;

&lt;p&gt;That's a much nicer foundation than a folder containing 37 shell scripts named things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;backup-final-v2-real-final.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Auth &amp;amp; Admin Reference:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.liorandb.com/docs/driver/auth-and-admin" rel="noopener noreferrer"&gt;https://docs.liorandb.com/docs/driver/auth-and-admin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 8 → Auth, Users &amp;amp; Roles&lt;br&gt;
&lt;strong&gt;Next:&lt;/strong&gt; Part 10 → Official LioranDB CLI&lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #8: Authentication, Users, Roles and Sessions</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:10:12 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-8-authentication-users-roles-and-sessions-38g6</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-8-authentication-users-roles-and-sessions-38g6</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #8: Authentication, Users, Roles and Sessions
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A database isn't production infrastructure if everyone connecting to it effectively becomes root.&lt;/p&gt;

&lt;p&gt;LioranDB exposes authentication and authorization through the same TypeScript client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;login&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&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="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client also exposes session operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;me&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listSessions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logoutAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatic token refresh
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&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;LioranDBClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;autoRefreshTokens&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The driver's token manager can then handle session refresh automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a user
&lt;/h2&gt;

&lt;p&gt;Administrative clients can use &lt;code&gt;UsersService&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;analytics-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SuperStrongPassword123!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;roles&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="s2"&gt;read_only&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;must_change_password&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manage it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;enabled&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="na"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;team&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;analytics&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeSessions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Roles
&lt;/h2&gt;

&lt;p&gt;Instead of scattering permissions directly across application logic, create roles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;role&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRole&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="s2"&gt;readers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;grants&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="na"&gt;permission&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DocumentRead&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

      &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;database&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&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="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Permission scopes
&lt;/h2&gt;

&lt;p&gt;Permissions can be scoped at different levels.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&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 typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;database&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;collection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you a useful building block for least-privilege application accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Application pattern
&lt;/h2&gt;

&lt;p&gt;Don't make every service use the administrator account.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Admin / Operations
    → administrative role

Backend API
    → application-specific read/write role

Analytics
    → read-only role

Backup worker
    → backup permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fewer permissions a compromised credential has, the smaller your blast radius.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Auth &amp;amp; Admin Docs:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.liorandb.com/docs/driver/auth-and-admin" rel="noopener noreferrer"&gt;https://docs.liorandb.com/docs/driver/auth-and-admin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 7 → Aggregation&lt;br&gt;
&lt;strong&gt;Next:&lt;/strong&gt; Part 9 → Cluster, Backups &amp;amp; Operational APIs&lt;/p&gt;



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



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
    <item>
      <title>LioranDB TypeScript Series #7: Building Aggregation Pipelines in TypeScript</title>
      <dc:creator>Swaraj Puppalwar</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:08:53 +0000</pubDate>
      <link>https://dev.to/ultrontheai/liorandb-typescript-series-7-building-aggregation-pipelines-in-typescript-4gcb</link>
      <guid>https://dev.to/ultrontheai/liorandb-typescript-series-7-building-aggregation-pipelines-in-typescript-4gcb</guid>
      <description>&lt;h1&gt;
  
  
  LioranDB TypeScript Series #7: Building Aggregation Pipelines in TypeScript
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LioranDB TypeScript Series:&lt;/strong&gt; Build with a developer-first document database powered by Rust and designed for TypeScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CRUD gets data in and out.&lt;/p&gt;

&lt;p&gt;Aggregation starts turning those documents into answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your first pipeline
&lt;/h2&gt;

&lt;p&gt;Suppose our products contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;inStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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;We want to count available products by category.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&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;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;inStock&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="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$category&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;$sum&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="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="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Documents
   ↓
$match
   ↓
$group
   ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add projection
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&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;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;inStock&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="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$category&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;$sum&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="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="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;count&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="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&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;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Current verified stages
&lt;/h2&gt;

&lt;p&gt;In the current pre-alpha release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$match&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$group&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$project&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$skip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$limit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are the core documented/verified stages.&lt;/p&gt;

&lt;p&gt;The aggregation API is intentionally still evolving.&lt;/p&gt;

&lt;h2&gt;
  
  
  AggregationCursor behavior
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;aggregate()&lt;/code&gt; returns an &lt;code&gt;AggregationCursor&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pipeline&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;results&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;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One important implementation detail in the current driver is that the aggregation result is materialized when the cursor initially loads.&lt;/p&gt;

&lt;p&gt;For very large result sets, don't automatically treat aggregation like incremental &lt;code&gt;find()&lt;/code&gt; pagination.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should I use &lt;code&gt;find()&lt;/code&gt; instead?
&lt;/h2&gt;

&lt;p&gt;If all you're doing is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filtering&lt;/li&gt;
&lt;li&gt;projection&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;limiting records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then &lt;code&gt;find()&lt;/code&gt; may be the simpler tool.&lt;/p&gt;

&lt;p&gt;Use aggregation when you're actually transforming or grouping data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Need documents?
    → find()

Need derived results?
    → aggregate()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pre-alpha limitations are intentional
&lt;/h2&gt;

&lt;p&gt;This is one area where the API will become substantially richer over time.&lt;/p&gt;

&lt;p&gt;I'd rather document the stages that work today than publish a giant MongoDB compatibility table containing features that don't exist yet.&lt;/p&gt;

&lt;p&gt;Pre-alpha should be explicit about its edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://docs.liorandb.com" rel="noopener noreferrer"&gt;https://docs.liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://liorandb.com" rel="noopener noreferrer"&gt;https://liorandb.com&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Driver:&lt;/strong&gt; &lt;code&gt;@liorandb/driver@2.0.5&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Previous:&lt;/strong&gt; Part 6 → Indexes&lt;br&gt;
&lt;strong&gt;Next:&lt;/strong&gt; Part 8 → Authentication, Users, Roles &amp;amp; Sessions&lt;/p&gt;



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

&lt;/div&gt;

</description>
      <category>liorandb</category>
      <category>typescript</category>
      <category>database</category>
      <category>rust</category>
    </item>
  </channel>
</rss>
