DEV Community

zisam shaikh
zisam shaikh

Posted on

Zero-Dependency Architecture: Why We Built KVDock with 0 External Dependencies

Run npm ls on a typical modern backend repository, and you will likely find 1,200+ transitive dependencies.

Every single external package your project imports is an implicit contract:

  • A potential security vulnerability or supply chain attack surface.
  • A source of bundle bloat and slow cold starts in serverless runtimes.
  • A potential breaking change when migrating between Node.js, Bun, Deno, and Edge runtimes.

When building KVDock, we set a radical architectural constraint: Zero runtime dependencies in core.

Here is how we engineered an enterprise-grade multi-tier key-value engine with zero external dependencies—and why this architecture is the future of edge and cloud software.


The Hidden Cost of "Convenience" Libraries

Most caching libraries pull in packages for:

  1. LRU Eviction: Pulling in lru-cache or mnemonist.
  2. Serialization: Pulling in heavy custom encoders.
  3. Promise Mutexes: Pulling in async-mutex or p-limit.
  4. Time & Clocks: Pulling in date-utility packages.

In a traditional microservice, this means your simple cache driver drags 15 to 40 transitive packages into your node_modules. If you deploy to Cloudflare Workers or AWS Lambda, every extra megabyte increases initialization latency and memory consumption.


1. Zero-Dependency $O(1)$ LRU with Native Doubly-Linked Lists

Instead of importing an external cache library, we implemented an intrusive doubly-linked list mapped to a native JavaScript Map:

// MemoryAdapter core: 0 dependencies
export class MemoryAdapter implements StorageAdapter {
  private map = new Map<string, CacheNode>();
  private head: CacheNode | null = null;
  private tail: CacheNode | null = null;

  public async get<T>(key: string): Promise<T | null> {
    const node = this.map.get(key);
    if (!node) return null;
    if (node.expiresAt && Date.now() > node.expiresAt) {
      this.evict(node);
      return null;
    }
    this.moveToHead(node); // O(1) touch
    return node.value as T;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Performance: Sub-50-nanosecond cache hits directly in V8 heap memory.
  • Byte-Sized Guard: Optional memory limit enforcement calculating UTF-8 byte weights natively without external dependencies.

2. In-Flight Promise Coalescing Without External Mutexes

Stopping cache stampedes usually involves complex locking libraries. In KVDock, single-flight deduplication is handled natively using promise references:

public async getOrSet<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
  const running = this.inFlight.get(key);
  if (running) return (await running) as T;

  const task = (async () => {
    try {
      const cached = await this.get<T>(key);
      if (cached !== null) return cached;
      const fresh = await fetcher();
      await this.set(key, fresh);
      return fresh;
    } finally {
      this.inFlight.delete(key);
    }
  })();

  this.inFlight.set(key, task);
  return (await task) as T;
}
Enter fullscreen mode Exit fullscreen mode

Under 1,000 concurrent requests, exactly 1 execution occurs. 999 callers await the same in-flight task.


3. Universal Edge & Cloud Neutrality

Because core KVDock has zero native C++ bindings and zero npm dependencies, it runs deterministically anywhere JavaScript runs:

  • Node.js (>= 18)
  • Bun (native fast path)
  • Deno
  • Cloudflare Workers & Pages
  • Vercel Edge Functions
  • Web Browsers & PWAs

And when you do need external drivers (like Redis, SQLite, S3, or DynamoDB), KVDock exports them as isolated, tree-shakeable sub-paths (kvdock/adapters/redis, kvdock/adapters/sqlite), ensuring your core bundle remains razor-thin.


⭐ Check out the source code: github.com/zisam-glitch/kvdock

👤 Follow the creator: @zisam-glitch for low-latency systems architecture!

Top comments (0)