local-notepad
v1.0.0
Published
Shared notepad for local network - easily share curl commands and notes
Downloads
20
Maintainers
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-notepadand you're done
Quick Start
NPX (Recommended)
npx local-notepadThat'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 -dManual
git clone https://github.com/your-username/local-notepad.git
cd local-notepad
npm install
npm startConfiguration
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-notepadOr with Docker:
PORT=8080 docker compose up -dHow It Works
- Open the app in your browser
- Enter a nickname (no sign-up needed)
- Create notes - everyone on the same network sees them in real-time
- 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 alicePOST /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/rawGET /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: noindexheader 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
