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

@ryopc/koshi

v3.0.0

Published

Terminal-native P2P decentralized SNS — serverless koshi board v3

Readme

🏄 koshi — Terminal-Native Decentralized SNS

Version 2.0.2 · MIT License · by game_ryo

A terminal-native, decentralized social network powered by ed25519 cryptography.


✨ Features

v2.0.2 — バグ修正・安定性向上 🎉

  • 🔐 Decentralized Auth — ed25519 keypair authentication (Nostr-inspired)
  • 📝 Posts — Create and view posts on the koshi board
  • 👥 Follow System — Follow/unfollow other users
  • ✉️ Direct Messages — Signed, private DMs
  • 💬 Real-time Chat — Interactive DM chat via WebSocket
  • 📡 Real-time Feed — WebSocket-powered live updates
  • ✏️ Profile Editing — Update your display name, bio, and avatar
  • 🛠️ Admin Controls — User management, account deletion, admin grants
  • 💻 Terminal-native — Beautiful CLI with chalk colors and spinners

🆕 New in v2.0

  • 🔑 Nostr Protocol Integration — Generate/manage Nostr keys (nsec/npub), push koshi posts to Nostr relays, pull events from the Nostr network, manage relay connections
  • 🖧 P2P Sync (hypercore) — Peer-to-peer data synchronization using hypercore + corestore + hyperswarm. Posts and DMs replicated across connected peers
  • 👥 Multi-Account Support — Manage multiple koshi identities from a single CLI. Switch between accounts with kb switch, interactive login, account removal
  • ⚙️ Enhanced Config — All credentials stored in ~/.config/koshi/config.json with support for per-account Nostr keys and P2P settings

📋 Table of Contents


🚀 Quick Start

# 1. Start the server (requires PostgreSQL)
DATABASE_URL=postgresql://user:pass@localhost:5432/koshi \
JWT_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))") \
node bin/server.js

# 2. Register a new account
kb register alice

# 3. Post to the koshi board
kb post "Hello, koshi! 🌊"

# 4. View your feed
kb feed

# 5. Start the real-time stream
kb realtime

📦 Installation

Global Install (CLI only)

# From npm (coming soon)
npm install -g @ryopc/koshi

# Or from source
git clone https://github.com/ryopc/koshi.git
cd koshi
npm install
npm link

Dependencies

  • Node.js >= 18.0.0
  • PostgreSQL >= 15.0 (hosted on Neon.tech in production)

💻 CLI Usage

The kb command is your gateway to the koshi board.

Commands

| Command | Description | |---------|-------------| | kb register <username> | Create a new account with ed25519 keypair | | kb login <username> | Authenticate using existing keypair | | kb whoami | Show your profile information | | kb post <message> | Create a new post on the koshi board | | kb feed [--limit=20] | Display your post feed | | kb follow <username> | Follow a user | | kb unfollow <username> | Unfollow a user | | kb dm <username> <message> | Send a direct message | | kb dms [--unread] | View your direct messages | | kb chat <username> | Start an interactive real-time DM chat | | kb edit-profile --display-name=... --bio=... | Update your own profile | | kb profile [username] | View a user profile | | kb search <query> | Search users by username | | kb realtime | Connect to the real-time event stream | | kb admin <command> | Admin commands (users, delete-user, grant, revoke) | | kb help [command] | Show help |

Examples

# Register a new user
kb register alice

# Login with existing keys
kb login alice

# Post something
kb post "Just joined koshi! 🌊"

# View feed
kb feed --limit=30

# Follow someone
kb follow bob

# Send a DM
kb dm bob "Hey, how's it going?"

# Start an interactive real-time DM chat
kb chat bob

# Edit your profile
kb edit-profile --display-name="Alice" --bio="Building the terminal future"

# Search for users
kb search alice

# Live stream
kb realtime

# Admin: list all users
kb admin users

# Admin: delete a user account (requires confirmation)
kb admin delete-user bob

# Admin: grant admin privileges
kb admin grant alice

Configuration

Credentials are stored in ~/.config/koshi/config.json and ~/.snsrc.

Environment variables:

| Variable | Default | Description | |----------|---------|-------------| | KOSHI_API_URL | https://koshi-api.ryopc.f5.si | API base URL | | KOSHI_WS_URL | wss://koshi-api.ryopc.f5.si | WebSocket URL |


🖥️ Server Setup

Local Development

# 1. Clone and install
git clone https://github.com/ryopc/koshi.git
cd koshi
npm install

# 2. Set up PostgreSQL database
createdb koshi

# 3. Run database migrations
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/koshi \
JWT_SECRET=dev-secret-change-in-production \
node src/db/migrate.js

# 4. Start the server
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/koshi \
JWT_SECRET=dev-secret-change-in-production \
node bin/server.js

Or use the .env file:

cp .env.example .env
# Edit .env with your database credentials
npm run migrate
npm start

Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | DATABASE_URL | ✅ | PostgreSQL connection string | | JWT_SECRET | ✅ | Secret key for JWT signing | | PORT | ❌ | Server port (default: 3000) | | NODE_ENV | ❌ | development or production | | LOG_LEVEL | ❌ | Log level (default: debug in dev, info in prod) |


📡 API Reference

Base URL

Development: http://localhost:3000/api Production: https://koshi-api.ryopc.f5.si/api

Authentication

All authenticated endpoints require a JWT Bearer token:

Authorization: Bearer <token>

Endpoints

Auth

| Method | Path | Auth | Description | |--------|------|------|-------------| | POST | /api/auth/register | No | Register a new user | | POST | /api/auth/login | No | Login with signature |

Users

| Method | Path | Auth | Description | |--------|------|------|-------------| | GET | /api/users/:username | No | Get user profile | | PUT | /api/users/me | Yes | Update own profile | | GET | /api/users/:id/followers | No | Get followers | | GET | /api/users/:id/following | No | Get following | | POST | /api/users/:id/follow | Yes | Follow a user | | DELETE | /api/users/:id/follow | Yes | Unfollow a user | | GET | /api/users/search/:query | No | Search users |

Posts

| Method | Path | Auth | Description | |--------|------|------|-------------| | GET | /api/posts/feed | Optional | Get post feed | | POST | /api/posts | Yes | Create a post | | GET | /api/posts/:id | No | Get a single post |

DMs

| Method | Path | Auth | Description | |--------|------|------|-------------| | GET | /api/dms | Yes | Get DM inbox | | POST | /api/dms/:userId | Yes | Send a DM | | PUT | /api/dms/:id/read | Yes | Mark DM as read | | GET | /api/dms/unread/count | Yes | Count unread DMs |

Admin

| Method | Path | Auth | Description | |--------|------|------|-------------| | GET | /api/admin/users | Admin | List all users | | GET | /api/admin/users/:id | Admin | Get user details (with keys, DM count) | | DELETE | /api/admin/users/:id | Admin | Permanently delete a user account | | PUT | /api/admin/users/:id/admin | Admin | Grant or revoke admin privileges |

Admin privileges: Set ADMIN_USERNAME environment variable, or mark user as admin via UPDATE users SET is_admin = TRUE WHERE username = '...';

WebSocket

Connect: ws://host:port/ws?token={jwt}

Events: message_sent, dm_received, user_online, user_offline, post_created, follow_notification

Health

| Method | Path | Description | |--------|------|-------------| | GET | /api/health | Health check |


☁️ Deployment

Render.com + Neon.tech (Recommended)

1. Set up Neon.tech Database

  1. Go to Neon.tech and create an account
  2. Create a new project (PostgreSQL 15)
  3. Get your connection string from Connection DetailsDATABASE_URL
  4. For production, use the pooled connection string (with ?pgbouncer=true)

2. Deploy on Render.com

  1. Push this repo to GitHub
  2. Go to Render.com and connect your GitHub repo
  3. Render will auto-detect render.yaml (Blueprint) and create the service
  4. In Render dashboard, add environment variables:
    • DATABASE_URL — your Neon.tech connection string
    • JWT_SECRET — generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
  5. Render will auto-deploy on every push to main

Alternative: Manual Setup on Render

If you prefer not to use Blueprint:

  1. Create a new Web Service on Render
  2. Connect your GitHub repo
  3. Configure:
    • Name: koshi-api
    • Environment: Node
    • Build Command: npm ci
    • Start Command: node bin/server.js
    • Health Check Path: /api/health
    • Pre-Deploy Command: node src/db/migrate.js
  4. Add environment variables (see above)
  5. Deploy!

Docker

# Build the image
docker build -t koshi-api .

# Run the container
docker run -d \
  --name koshi-api \
  -p 3000:3000 \
  -e DATABASE_URL=postgresql://... \
  -e JWT_SECRET=... \
  koshi-api

Docker Compose

version: '3.8'
services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: koshi
      POSTGRES_PASSWORD: postgres
    volumes:
      - pgdata:/var/lib/postgresql/data

  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://postgres:postgres@db:5432/koshi
      JWT_SECRET: change-this-in-production
    depends_on:
      - db

volumes:
  pgdata:

🔒 Security

  • Ed25519 Signatures — All posts and DMs are signed for authenticity
  • JWT Auth — Tokens expire after 24 hours
  • Admin Auth — Admin-only endpoints protected by requireAdmin middleware
  • Rate Limiting — Auth endpoints limited to 10 req/min per IP
  • SQL Injection Prevention — Parameterized queries throughout
  • Input Validation — All endpoints validate input
  • Helmet — Security headers enabled
  • No Hardcoded Secrets — Everything via environment variables
  • CORS — Restricted to CLI client origins

🧪 Development

# Run tests
npm test

# Run linter
npm run lint

# Run with auto-reload
npm run dev

# Run migration
npm run migrate

Project Structure

koshi/
├── bin/
│   ├── cli.js           # CLI/TUI entry point
│   └── server.js         # Express + WebSocket server
├── src/
│   ├── api/
│   │   ├── auth.js       # Auth routes (register/login)
│   │   ├── users.js      # User management routes
│   │   ├── posts.js      # Posts routes (koshi board)
│   │   ├── dms.js        # Direct messages routes
│   │   └── admin.js      # Admin routes (users, delete, grant)
│   ├── auth/
│   │   ├── ed25519.js    # Ed25519 crypto utilities
│   │   ├── jwt.js        # JWT token utilities
│   │   └── utils.js      # Hex encoding utilities
│   ├── db/
│   │   ├── schema.sql    # PostgreSQL schema
│   │   ├── migrate.js    # Migration script
│   │   └── pool.js       # Database connection pool
│   ├── middleware/
│   │   ├── auth.js       # Auth middleware
│   │   └── rateLimit.js  # Rate limiting middleware
│   ├── ws/
│   │   ├── index.js      # WebSocket server
│   │   └── handlers.js   # WebSocket message handlers
│   └── index.js          # Express app setup + logger
├── package.json
├── Dockerfile
├── render.yaml           # Render Blueprint (deployment config)
├── .env.example
└── .github/workflows/deploy.yml

📄 License

MIT — see LICENSE.


🙏 Acknowledgments