
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
Turn your Nostr long-form posts (NIP-23) into a fast, standalone static blog.
Turn your Nostr long-form posts (NIP-23) into a fast, standalone static blog. One command, no config.
📦 Available on npm: npmjs.com/package/nostrpress
npub or nprofile./blog (or custom --out directory)Direct CLI Arguments (via npx)
npx nostrpress npub1...
npx nostrpress npub1... --out ./public/blog --url https://myblog.com
Environment Variables
NPUB=npub1... npx nostrpress
Bun
bunx nostrpress npub1...
Output lands in ./blog/ (or your --out directory) — ready to serve.
The generated ./blog folder is pure static HTML/CSS/JS. Output directly to your framework's public directory with --out (or copy it):
// package.json
{
"scripts": {
"blog:fetch": "npx nostrpress npub1... --out ./public/blog",
"dev": "vite",
"build": "npm run blog:fetch && vite build",
"preview": "vite preview"
}
}
Blog lives at /blog/ alongside your Vue app. No vite config changes needed — Vite serves everything in public/ automatically.
Vite + React:
{
"scripts": {
"blog:fetch": "npx nostrpress npub1... --out ./public/blog",
"dev": "vite",
"build": "npm run blog:fetch && vite build"
}
}
Create React App:
{
"scripts": {
"blog:fetch": "npx nostrpress npub1... --out ./public/blog",
"start": "react-scripts start",
"build": "npm run blog:fetch && react-scripts build"
}
}
{
"scripts": {
"blog:fetch": "npx nostrpress npub1... --out ./public/blog",
"dev": "nuxt dev",
"build": "npm run blog:fetch && nuxt build",
"generate": "npm run blog:fetch && nuxt generate"
}
}
{
"scripts": {
"blog:fetch": "npx nostrpress npub1... --out ./public/blog",
"dev": "next dev",
"build": "npm run blog:fetch && next build"
}
}
npx nostrpress npub1...
# serve ./blog with any static web server
npx serve ./blog
blog/
├── index.html ← homepage with profile & post index
├── your-post-slug.html ← individual article pages
├── tags/
│ └── tag-name/
│ └── index.html ← posts filtered by tag
├── assets/
│ ├── images/ ← downloaded & cached media assets
│ └── videos/ ← downloaded & cached video files
├── css/
│ ├── site.css ← compiled stylesheet
│ └── print.css ← print stylesheet
└── js/
└── site.js ← theme switcher & client helpers
| Flag | Description | Default |
|---|---|---|
<npub_or_nprofile> | Your Nostr public key (npub1...) or profile (nprofile1...) | Positional |
-n, --npub <key> | Explicit flag for npub or nprofile | $NPUB |
-o, --out <dir> | Output folder for static blog | ./blog |
-u, --url <url> | Canonical site URL (enables RSS feed, sitemap & SEO tags) | $SITE_URL |
-r, --relay <relay> | Custom relay URL (can be specified multiple times) | Default relays + NIP-65 |
-c, --clean | Clear local cache before building | false |
--no-media | Skip downloading media assets locally | false |
-h, --help | Show help message | — |
-v, --version | Show version | — |
| Variable | Required | Description |
|---|---|---|
NPUB | ✅ yes (or pass as CLI arg) | Your Nostr public key (npub1...) or profile (nprofile1...) |
SITE_URL | optional | Canonical base URL (e.g. https://myblog.com). Enables RSS (/feed.xml), sitemap (/sitemap.xml), and canonical link tags. |
OUTPUT_DIR | optional | Output destination (default: ./blog) |
RELAYS | optional | Comma-separated list of custom relays |
CLEAN | optional | Set to true to clear cache before build |
npx nostrpress npub1... --out ./public/blog --url https://myblog.com
This generates:
public/blog/
├── index.html ← homepage with all posts & profile
├── feed.xml ← RSS 2.0 feed (latest 20 posts)
├── sitemap.xml ← XML sitemap (all pages + tag pages)
├── tags/ ← tag archive pages
├── assets/ ← locally downloaded and cached media
└── ...
FAQs
Turn your Nostr long-form posts (NIP-23) into a fast, standalone static blog.
We found that nostrpress demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.