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

ihateposting

v0.6.0

Published

Post to 14 social platforms from your terminal, your CI, or your AI agent.

Readme

ihateposting

Post to 14 social platforms from your terminal, your CI, or your AI agent.

Bluesky · X · LinkedIn · Facebook · Instagram · Threads · Pinterest · TikTok · YouTube · Mastodon · Telegram · Discord · Tumblr · Slack

npm install -g ihateposting
ihateposting login <key>          # key from Settings → Developers
ihateposting post "hello" --to bluesky,mastodon

Requires an iHatePosting account. Zero dependencies.

Drafts are the default

post saves a draft unless you say otherwise. Publishing to a real audience takes an explicit --now, and there is no flag that makes it implicit.

ihateposting post "text" --to linkedin                          # draft
ihateposting post "text" --to linkedin --at "2026-09-01 9:00 AM"  # scheduled
ihateposting post "text" --to linkedin --now                    # published

Times are in your account's timezone, the same one the web app uses.

Check before you spend a post

ihateposting post "…" --to x,youtube --now --check

--check creates nothing. It runs the same validation the publisher runs immediately before sending, so what it says is what will really happen — character counts (X weights links and CJK differently), missing media, required fields, accounts that are signed out, and your own plan's limits (an ended trial, a monthly allowance that is full). Exit code 1 means something would have stopped the post.

Give it the same flags you are about to post with — --now or --at, --media and any --option. Without them it checks a draft, and a draft is never capped.

Commands

| | | |---|---| | login <key> / logout | store or forget a key on this machine | | whoami | which account this key belongs to | | accounts | connected accounts, their handles and state | | platforms | per-platform limits, required fields, media rules | | boards | Pinterest board ids for --option pinterest.boardId (--account <id> picks the account) | | posts | your posts, newest first, and their status | | upload <file> | put an image or video in your media library; prints its id | | post "text" --to <list> | draft, schedule, or publish | | skill | write the AI agent skill into this project |

accounts, platforms, boards and posts take --json.

posts takes filters: --status (draft, scheduled, published, partial or failed), --from 2026-12-01 and --to 2026-12-31 (scheduled dates, inclusive), and --limit (default 50, at most 200).

upload takes --alt "a cat" for alt text, which several networks publish, and --json to print the whole asset instead of just its id. Attach uploads to a post with --media <ids>, comma separated:

id=$(ihateposting upload photo.jpg --alt "Launch day")
ihateposting post "We shipped" --to bluesky,linkedin --media "$id"

--to accepts platform names or the account ids from accounts. A name fans out to every connected account on that platform; use an id to pick one of two accounts on the same platform.

Platform settings

Some platforms need a setting before they will post: YouTube asks whether a video is made for kids, Pinterest needs a board. Pass each with --option <platform>.<key>=<value>, repeated as often as needed, and give --check the same ones:

ihateposting boards                     # Pinterest board ids
ihateposting post "New video" --to youtube,pinterest --media "$id" --at "2026-09-01 9:00 AM" \
  --option youtube.ytMadeForKids=no --option pinterest.boardId=549755885175000000

true and false are switches, '["a","b"]' is a list, and anything else is sent as text (numbers too, unless platforms --json lists that key as a number). platforms names what each platform requires. post refuses a flag it does not know rather than ignoring it, so a setting typed as its own flag never goes missing quietly.

In CI

There is nothing to log into. Set the key as an environment variable:

export IHATEPOSTING_API_KEY="pk_live_…"
ihateposting post "$MESSAGE" --to linkedin --now

The environment variable wins over a key stored by login, so a build machine can never silently post as whoever last used it.

IHATEPOSTING_API_URL overrides the API base if you are self-hosting.

AI agents

ihateposting skill

Writes .claude/skills/ihateposting/SKILL.md into the current project. Your agent then knows how to list accounts, validate a post, schedule one — and that it must not publish without being asked. Print it instead with ihateposting skill --print.

For editors that speak MCP, there is a server too: see Settings → Developers, or ihateposting-mcp.

Where the key lives

~/.ihateposting/config.json, created 0600. logout deletes it. Keys are created and revoked in Settings → Developers.

MIT