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

@xumana/cwp

v4.4.0

Published

Controlled WordPress — a CLI that moves WordPress sites between a local DDEV container and their host (Cloudron, ssh or local), guarding every upward write

Readme

cwp

Controlled WordPress: a CLI that moves WordPress sites between a local DDEV container and their host, guarding every upward write.

The name says what the tool does. Moving a WordPress site between environments is normally an unpredictable sequence of half-remembered commands. cwp makes every one of those movements controlled, and refuses the ones that are not.

cwp is middleware. It orchestrates DDEV, WP-CLI and your host, and adds the WordPress- and builder-specific glue those tools don't provide. It never reimplements what they already do: DDEV owns the local container, the host owns remote transport, WP-CLI owns WordPress. cwp owns sequencing, safety and project conventions.

Three hosts ship: Cloudron, a plain VPS over ssh, and local only. Two page builders ship: Bricks, and none, which is plain WordPress and a supported configuration rather than a degraded one.

You manage a handful of builder sites. Every time you refresh a local copy you hand-run wp db export, search-replace, upload copies and mail-guard plugins. This is that workflow with the footguns removed.


The manual is at cwp.sh/docs

One document rather than two, so there is no second copy to fall out of date. Below is what you need before deciding to click.

| | | |---|---| | Start here | What cwp is and is not · Requirements · Install · Quickstart · Choose your host | | Concepts | The two-layer config · Asymmetric data flow · Reproducibility · The safety model · The output contract · Providers · Builders · The site plugin | | Commands | One page each, generated from the CLI's own manifest | | Guides | The build loop · Onboarding an existing site · Uploads strategies · The scrub pipeline · Bricks integration · Hooks | | Reference | cwp.yml · Machine config · Exit codes | | Troubleshooting | Common failures and the command that fixes each |

The pages are in this repository too, under docs/, laid out so the directory structure is the site's route structure. A link between two of them works when you read them here and when you read them there.


Install

npm i -g @xumana/cwp
cwp --version
cwp doctor

Installed globally, once per machine. Project state lives in cwp.yml in the repository and in ~/.config/cwp/config.yml on your machine.

Requires Node ≥ 22, a Docker runtime, DDEV and mkcert, plus whatever your host needs: the Cloudron CLI and a login, or an ssh key. cwp doctor checks all of it at once, and every failure prints the command that fixes it.


Quickstart

From nothing to a working local copy of a production site:

mkdir -p ~/Code/example/example.com && cd ~/Code/example/example.com

cwp init                # scaffold: cwp.yml, .ddev/, the site plugin
ddev start
ddev wp core download   # core is gitignored, never in the repo

cwp fetch               # the themes and plugins the site needs to render
cwp adopt dev           # mint the relationship, derive the scope, build the tree
cwp db pull dev         # the database, scrubbed, with uploads proxied
cwp open

The first pull on an image-heavy site takes about two minutes, because uploads are proxied rather than copied.

Then take a baseline before you touch anything:

cwp db snapshot baseline

The full version, with what each step does, is at cwp.sh/docs/start/quickstart.

Day to day it is a loop rather than a setup: cwp db pull to start from what is live, build in the builder, cwp pull what you built, read the diff, commit, cwp deploy. Step three is the one people skip. Skipping it makes a deploy ship nothing you did: your work is in the database until something pulls it out.

The two pulls are different commands on purpose. cwp db pull replaces your local database with the site's; cwp pull reads the site's state into files you can diff and commit, and writes nothing to your local WordPress. The loop end to end is at cwp.sh/docs/guides/build-loop.


The safety model

Six rules, not configurable away. They are the whole reason this tool exists.

  1. Bulk data flows down, code flows up. Individually named items may flow upward under the full guard set, with every affected item printed first.
  2. Protected environments refuse upward writes without --force. cwp reads that list off the effects rather than off the command's name. That keeps the list complete rather than remembered.
  3. There is no bulk database push. Designed, then deferred.
  4. A remote restore point is taken before any upward write. On a host that cannot take one, disabling it makes the write refused.
  5. A local snapshot is taken before any downward write, and a snapshot that fails aborts the pull rather than warning.
  6. Every pull installs the mail guard, even with scrubbing switched off.

And one that is not a refusal: never raw SQL for URL replacement. WordPress stores serialised data, so it is always wp search-replace.

The source records twelve invariants as data, each naming the test that asserts it. The build fails when a named test is renamed or deleted. The long version is at cwp.sh/safety, and the catalogue is in src/domain/policy/invariants.ts.


Working on cwp itself

| | | |---|---| | docs/ARCHITECTURE.md | The design document for v1.0: the five layers, the seven-step spine, the two seams, the effect model. Start here. | | docs/SPEC.md | The world cwp runs against: what the external tools do, verified rather than derived. | | CLAUDE.md | Working conventions, and which document is authoritative for what. | | docs/features/, docs/bugs/ | What is planned, and what is broken, one file each; aimd next shows what is up. Everything is entered there before code. |

npm ci
npm run typecheck && npm run lint && npm test
npm run build            # tsup → dist/cli.js

The site is in site/, with its own package.json. The rules that govern what may be written on it are in site/CONTENT-RULES.md, and docs/WEBSITE.md is the whole record of how it was built.


Versioning and licence

Semantic versioning, tracked in VERSION.txt; changes in CHANGELOG.md, in Keep a Changelog format. GitLab CI publishes through npm's trusted publishing; no npm token exists anywhere in this project.

PolyForm Noncommercial 1.0.0 from 2.0.0 (LICENSE). Free for any noncommercial purpose: personal use, study, hobby projects, and use by charities, schools, public research and government. Commercial use needs a separate licence; write to [email protected].

Everything up to and including 1.0.0 is MIT and stays MIT (LICENSE-MIT). A licence already given cannot be taken back, and forks of those versions are legitimate.

Either licence covers cwp itself, not the tools it orchestrates: Cloudron, DDEV, WP-CLI and WordPress carry their own, and Bricks is commercial and licensed per site.