npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@khankudo/kisdb

v0.1.3

Published

KisDB is a zero-dependency library that is highly modular and can serve as a schemaless, realtime Database and as the primary API router for your small-scale personal project. It runs on Bun and can be interface-, protocol- and database-agnostic.

Readme

[!WARNING] KisDB is a personal passion project reaslitically only meant for myself to use. It has plenty of cool features that others certainly could enjoy, so I'm putting it here, but do NOT expect regular updates or any maintenance of any kind. Use at your own risk!

Introduction

KisDB is a zero-dependency library that is highly modular and can serve as a schemaless, realtime Database and the primary API router for your small-scale personal project. It runs on Bun and can be interface-, protocol- and database-agnostic. The main goal is to have the simplest and most flexible Developer Experience possible, even if some performance/efficiency has to be sacrificed. Personal projects should be built to push your imagination and skills, not dance around dependencies' limitations.

Motivation

I like building small, personal-use projects. I don't like designing and planning them. All Database/API solutions I could find were either DBaaS, lacked realtime-support or required fixed schemas that were difficult to constantly migrate during early development. I found myself having to first figure out the whole API & DB structure, decide on the tools that fit my needs best, get familiar with provided SDKs and then design my whole project around the tool's limitations. So instead of developing, I was just planning everything over and over again for each project. As one might think, this get's boring quite fast, so the projects ended up being abandoned before they really even began. No single Solution that I could find fit all my needs, so it was either deal with boring planning & repetitive design-work or abandon these kinds of projects I enjoy so much. So as any sane person would do; I chose to create KisDB :)

Goals

  • Realtime
    • easily subscribe to get updates for any values
  • DX over Everything
    • prioritize ease of use & flexibility instead of raw performance & efficiency
    • Built for small-scale personal projects, not enterprise-grade solutions
  • API Handling
    • interact with and define the project's logical API through the same interface
    • no duplicate connections
    • no separate dataflows
  • Schemaless support
    • DB & whole interface may never mandate a schema
    • schemas should of course be supported, but never required, only ever optional
    • Exponentially faster & easier early development
  • Client & Server
    • simplify development for both the client and the server
    • no cumbersome duplicates of anything ever again
  • Local Support
    • no cloud dependency
    • no lock-in to any service/company/product
  • No Dependencies
    • one shouldn't need a hundred different npm-packages just create a simple client & database/backend
  • Any Data
    • Must support Nested Objects, Key-Value-Pairs and Arrays/Lists
  • Any Protocol
    • Allow for protocol-modules to handle transport in any way they see fit
    • REST (http/s), WebSocket, MQTT, raw tcp/udp, ...
  • Any Interface
    • Allow flexible client interfaces (interoperable too):
    • Object-Oriented, Functional, VanillaJS, TypeScript, React, go, C/C++, ...

Overview

Viewer-Client-Server-DB Overview Diagram

KisDB consists of four module layers, each focusing only on it's own responsibilities with no additional requirements to consider.

Viewer - Client

The viewer is what transform the primitive KCPHandle Object a client provides into an actual programmatic interface for the developer to use to access their data and API endpoints. Any viewer can be chosen and freely used with any client, the developer can even make their own without needing to consider any of the other KisDB layers; simplicity and modularity at it's core. This boundary is what enables KisDB to be interface-agnostic, allowing for a personalized Developer Experience.

If you are using a custom client-server for a specific project, say for MQTT on a microcontroller, your client doesn't have to support a viewer, it itself can be both a client and a simple viewer. The separation exists in KisDB, so that you can reuse the same client in the browser with different frameworks natively and much more reliably rather than having to chain multiple viewers on top of one another.

Client - Server

The Client and Server modules must always come in pairs. A single client module is only ever compatible and must explicitly be used with it's paired server module. They are responsible for transporting the data and requests. It does not matter how a server handles talking with it's client, the only requirement is that the server accepts a DB's KCPHandle and the client provides that KCPHandle to viewers. How they do it is completely irrelevant. This boundary is what enables KisDB to be protocol-agnostic, allowing wide hardware and programming language support.

Server - Database

The Server module accepts a KCPHandle Object from the Database Module and communicates using it. The server is responsible for assigning unique connection-ID to each client or omit it if stateless. Any server can work with any Database, there is also nothing stopping you from using multiple server in parallel providing different protocols for the same database. Changes are automatically reflected at all servers through the database-module, nothing needs to be tracked, managed or coordinated by the servers; they merely 'serve'. This boundary is what enables the separation of the transport-layer and the data-layer, allowing any client using any protocol to seamlessly integrate with the same underlying Application Logic & Data as any other client using any other protocol.

Database - Storage

The Database module is responsible for interacting with the actual DB-instance. It provides the standardized KCPHandle Object and translates it locally via e.g. SQLite or remotely using available specific SDKs such as mongoose, S3 or any SQL-interface. The Database module is also responsible for implementing all authentication and authorization methods. Middleware-style solutions could have been implemented for more flexibility, however since many databases already implement varying degrees of auth and even perhaps even realtime listening, etc. extracting those into layers would have made everything more complicated, less efficient and much more prone to bugs. This way, only the DB module is considered 'trusted-context', everything else needs to authenticate itself (yes even the application logic server needs a token, even if used locally)

Example

Here are very basic example snippets from the client & server. You can also just run the included dev-sample (p.s. zero-dependencies -> no bun install needed):

git clone https://github.com/KhanKudo/kisdb.git
cd kisdb
bun run dev

Client / Browser

import { createHttpClient } from '@khankudo/kisdb/client/http'
import { createVanillaViewer } from '@khankudo/kisdb/viewer/vanilla'

const client = createHttpClient(undefined, { token: '123' })
const DB = createVanillaViewer(client)

DB.$onnow = console.info
//info > {}
DB.x.$once = console.warn

console.log(await DB.x) //> undefined
DB.x = 5
//info > {x:5}
//warn > 5
console.log(await DB.x) //> 5
delete DB.x
//info > {}

console.log(await DB.rnd()) //> -1..1 (random number)
console.log(await DB.rnd()) //> -1..1 (random number)
console.log(await DB.rnd()) //> -1..1 (random number)

DB.x.$off = console.info

Server / Bun

import { createSQLiteHandle, destroySQLiteHandle } from "@khankudo/kisdb/db/sqlite"
import { createHttpRoutes } from "@khankudo/kisdb/server/http"
import { createDirectClient } from "@khankudo/kisdb/client/direct"
import { createVanillaViewer } from "@khankudo/kisdb/viewer/vanilla"
import { createAdminHelper } from "../core/admin"
import { EVERYONE, SUPERADMIN, USERS } from "../core/auth"

export type MyDB = {
  '': {
    x?: number
    rnd: () => number
  }
}

const handle = await createSQLiteHandle<MyDB>('my_app') // bun:sqlite ./my_app.db

// helper with various methods for database/server administration
const admin = await createAdminHelper(handle, 'DEFAULT_PA$$WORD')
// set default permissions for path '' to be owned by root, read: all, write: only authenticated, execute: all
await admin.ensureAccess('', SUPERADMIN, EVERYONE, USERS, EVERYONE)
// create a demo account with password 'demo' and token '123', (true keeps already existing tokens, e.g. after reboot)
await admin.ensureUser('demo', 'demo', true, '123')
// create a server account with login disabled and token '456', (true keeps already existing tokens, e.g. after reboot)
await admin.ensureUser('server', false, true, '456')
// invalidate the admin object - destroy internal token
await admin.destroy()

const direct = createDirectClient(handle, {
  connection: 0,
  token: Bun.env.SERVER_TOKEN ?? '456'
})
const DB = createVanillaViewer(direct,'')

DB.rnd = async () => {
  return Math.random() * 2 - 1
}

DB.x.$onnow = (value) => {
  console.log('x is', value)
}

const server = Bun.serve({ routes: createHttpRoutes(handle) })
console.log('Ready! ( http://localhost:3000 )')

process.on('exit', () => {
  server.stop(true)
  destroySQLiteHandle(handle)
})

API Reference

KCPHandle

ToDo

Helpers

ToDo

Notes on AI

This project has zero AI-generated code or content of any kind. No agent, in-editor or project-context-aware AI was ever used for anything at all. Some microsnippets (~5 lines of code) might have come from AI. I still love to simply google for stuff (actually Brave/DDG) and look through Documentation/StackOverflow/Reddit results but sometimes nothing comes up. Some tools or problems are too new, since AI noone sadly really posts solutions or questions on forums anymore. So my AI-philosophy is to use it as a modern-day search engine. The same way people would traditionally have used StackOverflow or Google Search (the good old one). I treat AI answers the same way I treat any zero-vote, zero-comment StackOverflow response: Cautiously optimistic.

The way we search the internet may have changed, my way of using it and it's content however has not. After all, even if one hard-headedly never interacts with AI themselves, there is no more way of knowing if any content on the internet came from an AI, a human, or simply a human using AI. As such if one wishes to guarantee never using anything AI-generated, one must simply stop using the internet; I won't do that.