Skip to content

Conversation

@adamziel
Copy link
Collaborator

@adamziel adamziel commented Dec 15, 2025

Summary

This PR introduces a new start command to Playground CLI that provides a simple, wp-now-style experience for running WordPress locally. It's designed to make the CLI accessible to developers who just want to run a command and get going, without needing to understand low-level options.

The existing server command remains available for advanced users who need fine-grained control over mounts, WordPress installation modes, and other low-level options.

Migrating from wp-now

This change unlocks officially deprecating @wp-now/wp-now and recommending everyone switch to @wp-playground/cli. Here's how wp-now commands map to the new start command:

wp-now Playground CLI
npx @wp-now/wp-now start npx @wp-playground/cli start
wp-now start --php=8.3 playground start --php=8.3
wp-now start --wp=6.7 playground start --wp=6.7
wp-now start --port=8000 playground start --port=8000
wp-now start --blueprint=bp.json playground start --blueprint=bp.json
wp-now start --path=./my-plugin playground start --path=./my-plugin
wp-now start --skip-browser playground start --skip-browser
wp-now start --reset playground start --reset (implemented in #3119)

The API is intentionally similar. Both tools automatically detect plugin, theme, wp-content, or WordPress directories. Both work with no additional flags.

Improvements over wp-now:

  • Auto-login by default: No need to manually log in after starting
  • Browser opens automatically: Site launches in your default browser (use --skip-browser to disable)
  • Manual mounts available: Use --mount /host/path:/vfs/path for additional mounts beyond auto-detection
  • Escape hatch: Use --no-auto-mount to disable auto-detection and manually control mounts
  • Site URL override: Use --site-url when you need a specific URL

Differences with wp-now:

  • Playground CLI does not persist sites in the same way as wp-now does. In wp-now, you can run wp-now start in a directory, get a site, make some changes to that site, then close the server, come back the next day, start the server again, and continue working on that same site. Playground CLI doesn't do it. Every server is ephemeral. You can store your changes by explicitly mounting wp-content to a local directory, but there's no automation in place to do it for you. If the users will request this feature, we can consider adding it, but I'm skipping it in the initial rollout as it would add a lot of complexity that the Playground CLI tool was intentionally designed not to handle implicitly.

^ This was implemented later on in #3119

Usage

# Start in current directory (auto-detects project type)
playground start

# Reset the previously created site and start fresh
playground start --reset

# Start with a specific path
playground start --path=./my-plugin

# Use specific PHP and WordPress versions
playground start --wp=6.7 --php=8.3

# Don't open browser automatically
playground start --skip-browser

# Enable Xdebug for debugging
playground start --xdebug

# Disable auto-detection and use manual mounts
playground start --no-auto-mount --mount ./my-plugin:/wordpress/wp-content/plugins/my-plugin

# Override the site URL
playground start --site-url=https://my-local-site.test

CLI Flags Reference

Flag Type Default Description
--path string current directory Path to the project directory. Playground auto-detects if this is a plugin, theme, wp-content, or WordPress directory.
--php string 8.3 PHP version to use. Choices: 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5
--wp string latest WordPress version to use.
--port number 9400 Port to listen on.
--blueprint string Path to a Blueprint JSON file to execute on startup.
--login boolean true Auto-login as the admin user.
--xdebug boolean false Enable Xdebug for debugging.
--skip-browser boolean false Do not open the site in your default browser on startup.
--quiet boolean false Suppress non-essential output.
--site-url string Override the site URL. By default, derived from the port (http://127.0.0.1:<port>).
--mount array Mount a directory to the PHP runtime (can be used multiple times). Format: /host/path:/vfs/path. Use this for additional mounts beyond auto-detection.
--no-auto-mount boolean false Disable automatic project type detection. Use --mount to manually specify mounts instead.

Test plan

  • Run playground start --help and verify options are displayed correctly
  • Run playground start in a plugin directory and verify auto-detection works
  • Verify browser opens automatically on startup
  • Verify --skip-browser suppresses browser opening
  • Run existing CLI tests to ensure no regressions

…ment

Introduces a new `start` command that provides a simple, wp-now-style experience
for running WordPress locally. While the existing `server` command offers powerful
low-level options for advanced use cases, `start` is designed for developers who
just want to run a command and get going.

The command auto-detects project types (plugin, theme, wp-content, WordPress),
enables auto-login by default, and opens the browser automatically. It accepts
manual mounts via --mount and allows disabling auto-detection with --no-auto-detect
for users who need more control.
@Samiullahstanikzai
Copy link

i have this same issue Runtime error
Playground crashed

@adamziel
Copy link
Collaborator Author

@Samiullahstanikzai would you open a new issue with more details and reproduction instructions?

@adamziel
Copy link
Collaborator Author

@JanJakes @fellyph @zaerl Would you mind taking a look at this one? I'd love to learn how intuitive this seems for you? how smooth of a migration path would that be from WP now? And if anything obviously is missing or could be adjusted to make this even more useful?

@akirk
Copy link
Member

akirk commented Dec 16, 2025

Could we make the command even shorter? Just: npx @wp-playground/cli

@adamziel
Copy link
Collaborator Author

@akirk I think so! Or maybe even just npx wp-playground – I've secured that name.

}

export function isPluginFilename(path: string): boolean {
export function isPluginDirectory(path: string): boolean {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function accepts a directory path, let's call it accordingly

@adamziel
Copy link
Collaborator Author

Well, I'll go ahead and merge

@adamziel adamziel merged commit 238a3f5 into trunk Jan 13, 2026
33 checks passed
@adamziel adamziel deleted the easy-cli-command branch January 13, 2026 11:45
@fellyph
Copy link
Collaborator

fellyph commented Jan 13, 2026

That is great, @adamziel. I will document it and create a post about it. Is this the complete deprecation of wp-now?

@adamziel
Copy link
Collaborator Author

@fellyph there's still one prominent difference – wp-now will start the same site every time you run it in the same directory while @wp-playground start starts a new site every time. I wondered how important this might be and reviewed the existing references to wp-now and found that:

It's not a lot of projects, but offering a migration path would be kind. Let me see if there's an easy way to offer that feature 👀

@adamziel
Copy link
Collaborator Author

adamziel commented Jan 13, 2026

It wasn't that complicated so I just opened #3119. Once it's merged, we'll have a clear migration path from wp-now.

Edit: It's merged!

@swissspidy
Copy link
Member

Looking forward to migrate once this is released

adamziel added a commit that referenced this pull request Jan 13, 2026
## Motivation for the change, related issues

Makes `npx @wp-playground/cli start` persist the created site – just
like `wp-now` does. With this PR, Playground CLI has a feature parity
with wp-cli and we can move forward with the `wp-now` deprecation.

Follow-ups on
#3040

## Implementation details

Whenever there's no mount specified for `/wordpress`, Playground CLI
will mount the host path `~/.wordpress-playground/sites/<path hash>` at
the `/wordpress` VFS location.

There's also a `--reset` CLI flag that wipes out the stored files and
starts a fresh site.

That's the gist of it.

This simple logic comes with a few caveats:

* The `~/.wordpress-playground` mount will not happen if the user
explicitly mounts `/my/cool/site` at `/wordpress`. We can't mount two
host directories at `/wordpress` so the explicit path wins.
* The `~/.wordpress-playground` mount will not happen if the auto
mounting is enabled, and the `/my/project/path` contains a full
WordPress installation. The reason is the same as above.
* I've removed the "just mount `cwd` at `/wordpress`" fallback in the
auto-mounting logic. It doesn't seem that useful and it also interfered
with the `~/.wordpress-playground` mount. If we really need that logic
in the future, we can restore it behind an explicit option.

I've also moved the `start` command logic inside the `runCli()`
function, it seems cleaner that way. Really, the CLI code could use some
cleanup sooner than later to clearly separate the Typescript definitions
for each command's args and clearly separate their handlers. But that's
out of scope here.

## Testing Instructions (or ideally a Blueprint)

* Run `nx dev playground-cli start`
* Change site title or add a page
* Kill the server
* Run `nx dev playground-cli start` again
* Confirm your changes are still there
* Kill the server
* Run `nx dev playground-cli start --reset-site`
* Confirm you got a fresh new site
@adamziel
Copy link
Collaborator Author

I'll see if I can get articles-adamziel-com#24 to work before releasing this. It would be nice to have a cleaner CLI output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants