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

@fullystudios/zed-npm-script-tasks

v0.1.1

Published

Generate a Zed .zed/tasks.json from every package.json#scripts in a repo, including monorepo workspace packages

Readme

@fullystudios/zed-npm-script-tasks

Generate a Zed .zed/tasks.json from every package.json#scripts in a repo, including monorepo workspace packages, so all of them are runnable from the cmd-shift-r task modal.

Why

Zed already surfaces package.json scripts, but only when a JS/TS/TSX or package.json buffer is the active editor, and it only walks upward from that file. Focus a README.md or a .toml, or no file at all, and they all disappear. Zed also never scans downward into workspace packages.

This writes the scripts to disk instead, so they are always in the modal regardless of what is focused, and monorepo packages are included.

This is a CLI, not a Zed extension. Zed's extension API has no filesystem write capability and no task-provider hook, so an extension cannot do this.

Install

Per project

npm install --save-dev @fullystudios/zed-npm-script-tasks

Add a script:

{
  "scripts": {
    "zed:sync-tasks": "npx zed-npm-script-tasks sync"
  }
}
npm run zed:sync-tasks

.zed/tasks.json is meant to be committed. Add npm run zed:sync-tasks -- --check to CI so a stale file fails the build.

Globally

Install once and run it in any repo, without adding a dependency or a script to that repo:

npm install --global @fullystudios/zed-npm-script-tasks
cd /path/to/repo
zed-npm-script-tasks sync

Or from anywhere, with --cwd:

zed-npm-script-tasks sync --cwd /path/to/repo

Either way the tool finds the repo root itself and writes <root>/.zed/tasks.json, so it does not matter which subdirectory you are standing in. The repo needs no node_modules at all: the version of the tool that runs is the global one, and the package manager it puts in the generated command is still read from the repo (its packageManager field or lockfile).

Useful for repos that are not yours to modify, or when you would rather not have a Zed-specific devDependency in every project. Keep the per-project install as well if you want --check in CI, since a globally installed, unpinned version is not something CI can reproduce.

Managing the global install:

npm install --global @fullystudios/zed-npm-script-tasks@latest  # upgrade
npm list --global --depth 0 | grep zed-npm-script-tasks         # which version
npm uninstall --global @fullystudios/zed-npm-script-tasks       # remove

pnpm (pnpm add --global), Yarn (yarn global add) and Bun (bun add --global) work too, as does running it without installing anything:

npx @fullystudios/zed-npm-script-tasks sync

Usage

zed-npm-script-tasks sync    [options]   write .zed/tasks.json
zed-npm-script-tasks watch   [options]   sync now, then re-sync when manifests change

  -c, --check       exit 1 if .zed/tasks.json is out of date; never writes (CI)
      --dry-run     print what would be written to stdout; never writes
      --cwd <dir>   start directory for root detection (default: process.cwd())
  -q, --quiet       suppress the summary line
  -h, --help        show this help
  -v, --version     show version

What it generates

One task per script, labelled <package name>: <script>:

[
  // >>> zed-npm-script-tasks:begin (generated - do not edit inside this block; run `zed-npm-script-tasks sync`)
  {
    "label": "site: dev",
    "command": "pnpm",
    "args": ["run", "dev"],
    "cwd": "$ZED_WORKTREE_ROOT/src/apps/site"
  },
  // <<< zed-npm-script-tasks:end
]

Labels are package-qualified because a name like check-types typically exists in many manifests at once. cwd uses Zed's $ZED_WORKTREE_ROOT variable, never an absolute path, so the committed file works on every machine.

Your own tasks are safe

Anything outside the sentinel comments is preserved byte-for-byte, including your comments and formatting. The file is never parsed and reserialized, only spliced.

  • No file yet: one is created.
  • File with a managed block: only the block's interior is replaced.
  • File without a managed block: a block is inserted above your existing tasks.
  • File that is not a JSON array, or whose hand-written part is already malformed: the tool refuses to write and tells you. This matters because Zed discards the entire file on a single parse error.

Writes are atomic (temp file plus rename) and skipped entirely when the result would be identical, so git status stays clean and Zed's file watcher is not churned.

Discovery

  • Root is the nearest ancestor with a package.json, preferring the git root, to match the directory you open in Zed.
  • Workspace packages come from pnpm-workspace.yaml packages, else package.json workspaces (array or { "packages": [...] }). Negated globs like !docs are honoured.
  • Only directories that actually contain a package.json count, so a glob like scripts/* will not pick up loose files, and build output such as .next/package.json is excluded.
  • Lifecycle hooks are skipped when their base script exists in the same manifest: postsync is dropped because sync exists, while preview and prepublishOnly are kept.
  • Package manager is the nearest packageManager field, else inferred from the root lockfile, else npm. Only the name is used, so Corepack or Volta still picks the version.
  • Packages with no scripts contribute nothing. A malformed manifest is warned about and skipped rather than failing the run.

Ordering is deterministic (root first, then packages by path; scripts in declaration order) so re-running produces a byte-identical file and readable diffs.

Duplicate entries in the modal

Zed's own providers also list package.json scripts when a JS/TS or package.json buffer is focused, so you may see a script up to three times (site: dev, run dev, package.json > dev). To show only these generated tasks, add to .zed/settings.json:

{
  "languages": {
    "JSON": { "tasks": { "enabled": false } },
    "TypeScript": { "tasks": { "enabled": false } }
  }
}

Caveats

  • Once any .zed/tasks.json exists in a worktree, Zed ignores all tasks in that worktree's .vscode/tasks.json. The tool warns when it first creates the file in a repo that has one.
  • Zed only lists a worktree's tasks when that worktree is the active one. Scripts from other folders in a multi-folder window will not appear.
  • Requires Node 22 or newer (fs.globSync).

Development

npm install
npm test          # node:test
npm run typecheck # tsc --noEmit over JSDoc types

Try it against another repo without installing it there:

node bin/cli.mjs sync --cwd /path/to/repo --dry-run

License

MIT