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

local-notepad

v1.0.0

Published

Shared notepad for local network - easily share curl commands and notes

Downloads

20

Readme

Local Notepad

A lightweight, real-time shared notepad for local networks. Share curl commands, JSON snippets, config files, and notes with anyone on the same network. Zero setup, zero accounts.

Features

  • Real-time - Notes appear instantly for all connected users via WebSocket
  • Zero setup - No accounts, no database. Run it and share the URL
  • Code-aware - Auto-detects and syntax-highlights code (bash, JSON, Python, Go, Rust, SQL, YAML, and more)
  • Markdown support - Write in markdown, rendered with full GFM support
  • Dark mode - Toggle or follow your system preference
  • Raw view - Access any note as plain text via /api/notes/:id/raw
  • Self-hosted - Runs on your machine, your network, your data
  • One command - npx local-notepad and you're done

Quick Start

NPX (Recommended)

npx local-notepad

That's it. Open http://localhost:9999 and share the network URL shown in the terminal with others on the same network.

Docker

docker compose up -d

Manual

git clone https://github.com/your-username/local-notepad.git
cd local-notepad
npm install
npm start

Configuration

All settings are configured via environment variables. Copy .env.example to .env and customize:

| Variable | Default | Description | |---|---|---| | PORT | 9999 | Server port | | MAX_NOTE_LENGTH | 10000 | Maximum characters per note | | MAX_NOTES_PER_USER | 100 | Maximum notes per user before oldest are cleaned up | | IDLE_TIMEOUT_MINUTES | 30 | Minutes before idle users and their notes are removed | | CLEANUP_INTERVAL_SECONDS | 60 | How often the cleanup job runs | | CORS_ORIGIN | * | Allowed CORS origins (comma-separated, or * for any) | | RATE_LIMIT_PER_MINUTE | 60 | Max API requests per minute per IP |

Docker with custom config

Edit docker-compose.yml or pass env vars directly:

PORT=8080 IDLE_TIMEOUT_MINUTES=60 npx local-notepad

Or with Docker:

PORT=8080 docker compose up -d

How It Works

  1. Open the app in your browser
  2. Enter a nickname (no sign-up needed)
  3. Create notes - everyone on the same network sees them in real-time
  4. Share the network URL with your team

Notes are stored in memory. They persist as long as the server is running and the user hasn't been idle beyond the configured timeout. Restart the server, and notes start fresh - by design.

Content Types

Notes are automatically rendered based on their content:

| Type | Detection | Rendering | |---|---|---| | Markdown | Headings, lists, bold, links, etc. | Full GFM rendering via marked | | Code | curl, git, npm, docker, python, go, rust, sql, json, yaml | Syntax highlighted via Prism.js | | Plain text | Everything else | Pre-wrapped text |

API

GET /api/notes

List all notes, optionally filtered by user.

GET /api/notes          # all notes
GET /api/notes?user=alice  # notes by alice

POST /api/notes

Create a new note.

curl -X POST http://localhost:9999/api/notes \
  -H "Content-Type: application/json" \
  -d '{"author": "alice", "content": "curl https://api.example.com/health"}'

DELETE /api/notes/:id

Delete a note (only the author can delete their own notes).

curl -X DELETE "http://localhost:9999/api/notes/NOTE_ID?author=alice"

PATCH /api/notes/:id/pin

Toggle pin status on a note (only the author can pin).

curl -X PATCH "http://localhost:9999/api/notes/NOTE_ID/pin?author=alice"

GET /api/notes/:id/raw

Get a note as plain text (useful for piping or scripting).

curl http://localhost:9999/api/notes/NOTE_ID/raw

GET /api/users

List all connected users.

WebSocket /ws

Connect to ws://localhost:9999/ws for real-time updates.

Client messages:

{ "type": "join", "name": "alice" }
{ "type": "heartbeat" }

Server messages:

{ "type": "note:created", "data": { ... } }
{ "type": "note:deleted", "data": { "id": "..." } }
{ "type": "note:updated", "data": { ... } }
{ "type": "user:joined", "data": { "name": "alice" } }
{ "type": "users:updated", "data": [ ... ] }

Tech Stack

  • Backend: Node.js, Express, ws (WebSocket)
  • Frontend: Vanilla JS, Prism.js (syntax highlighting), marked (markdown)
  • Storage: In-memory (Map)
  • No database required

Security Considerations

  • All note content is HTML-escaped to prevent XSS
  • Rate limiting is enabled by default (60 req/min per IP)
  • X-Robots-Tag: noindex header prevents search engine indexing
  • CORS is configurable (defaults to open for local network use)
  • Note length and count limits prevent abuse

Since this is designed for local/trusted networks, there is no authentication. If you expose it to the internet, use a VPN or reverse proxy with access controls.

License

MIT