This tutorial sets up everything you need to start writing block code. By the end you’ll have a working my-first-block plugin running in a local WordPress install.
What we’re building
A minimal block plugin scaffolded with the official WordPress CLI tool. We’re not building a custom block in this tutorial — that’s Part 3. Here we get the development environment right so writing the block in Part 3 is the fun bit.
Step 1 — Install Node.js
WordPress block development uses Node.js for tooling (build, lint, test). Install the LTS version from nodejs.org or via your package manager.
Step 2 — Get a local WordPress install
If you don’t already have one, pick the lightest tool:
- wp-now —
npx @wp-now/wp-now startspins up WordPress with no install. Great for quick experiments. - Local by Flywheel — GUI, free, full WP install with admin UI for SSL/SSH/etc.
- DDEV — Docker-based, scriptable, used by agencies. Heavier but reproducible.
For this series, we use wp-now because it’s the lowest-friction option.
Open http://localhost:8881/wp-admin/ (login: admin / password by default) — you have WordPress.
Step 3 — Scaffold a block plugin
The @wordpress/create-block tool creates a complete plugin skeleton with the build pipeline, sample block code, and package.json scripts pre-configured.
The CLI gives you a fully working block plugin. Let’s look at what it generated.
Step 4 — Tour the generated files
Four files matter most:
my-first-block.php— the plugin’s PHP entry. Tells WordPress “here’s a plugin” and callsregister_block_type()againstblock.json.block.json— the manifest. Lists the block name, title, category, supported features, attributes, file paths.src/index.js— the JavaScript entry. CallsregisterBlockType()from@wordpress/blockswith the edit + save components.src/edit.js/src/save.js— the React components.
Step 5 — Start the dev server
npm run start watches src/ and recompiles to build/ on save.
Leave that running. In another terminal (or your editor) you’ll edit files; webpack rebuilds on save automatically.
Step 6 — Activate the plugin
Go to wp-admin → Plugins. You’ll see “My First Block” in the list. Click Activate.
Open the editor
In wp-admin, go to Posts → Add New (or open any existing post).
Find your block
Click the + in the editor and search for “My First Block”. It appears under a default “Widgets” category.
Insert + view
Click the block to insert it. You’ll see the placeholder content from src/edit.js (the default scaffolded text). Confirm — your dev environment works end-to-end.
Verification
If npm run start is running and you can insert your block in a post, you’re set up correctly. Common stumbling blocks:
| Symptom | Fix |
|---|---|
| Plugin doesn’t appear in wp-admin | Plugin folder must be in wp-content/plugins/ — check pwd |
| Build fails on save | Node version too old; need 18+ |
| Block doesn’t appear in inserter | Hard-refresh the editor; you may have a stale browser cache |
block.json errors in console | Run npm run build once after create-block finishes — sometimes the initial build is needed |
What’s next
You have a working block development environment. Part 3 writes our first real custom block — a callout component with editable title and body, replacing the scaffolded placeholder with code you understand line-by-line.
Get the next one in your inbox. Practical tips, no fluff.
More tutorials
View all- WordPress
How to Prepare Your Plugin or Theme for WordPress 7.0
A step-by-step compatibility process for shipping a WordPress 7.0-ready release — set up a test site, audit your blocks, fix the breaking changes, and ship with confidence.
22 min
- WordPress
WordPress 7.0 for Block Developers: Breaking Changes
WordPress 7.0 enforces the iframed editor, broadens contentOnly mode, and drops PHP 7.3. Here are the breaking changes block and plugin developers must fix before users upgrade.
25 min
- WordPress
WordPress 7.0 AI: Client, Abilities & Connectors
The headline feature of WordPress 7.0 is native AI in Core. Here is what the WP AI Client, the Abilities API, and the Connectors system actually mean for plugin developers.
25 min