Skip to content


Getting started with _tw

Generate a theme repository, set up your development environment and build your first Tailwind-based WordPress theme.

Installing Tailwind

After unzipping your generated theme archive, your first step is to install npm if you haven’t already. After that, open your terminal of choice, navigate to your theme repository and run:

npm install
Code language: plaintext (plaintext)

With Tailwind installed, you can then generate your style.css file by running:

npm run dev
Code language: plaintext (plaintext)

This creates a development build of your theme’s stylesheet.

Setting up your development environment

Your generated theme won’t have a flat file structure like _s. Instead, you’ll see the following folders:

generated-theme-slug ├── scripts ├── tailwind └── theme

Alongside those folders you’ll find an assortment of package and configuration files that aren’t meant to be uploaded to WordPress as part of a theme. The theme itself lives in the theme folder, keeping those files together and uncluttered.

However, this folder structure means you can’t place your theme repository directly in your wp-content/themes folder.

I use VVV with the following folder structure:

development-website.test ├── generated-theme-slug │ ├── scripts │ ├── tailwind │ └── theme ├── log ├── provision └── public_html ├── wp-admin ├── wp-content └── wp-includes
Code language: plaintext (plaintext)

My preferred approach is to place my theme repository in the development site’s root folder (development-website.test in the example above), one level above WordPress (located in the public_html folder). I’ll then navigate to the wp-content/themes folder and create a symbolic link to place my generated theme’s theme subfolder into the WordPress themes directory:

ln -s ../../../generated-theme-slug/theme generated-theme
Code language: plaintext (plaintext)

I then activate the theme in WordPress, and any changes I make to the theme are immediately reflected on the development site.

Another option is to place the theme repository in the wp-content folder, navigate to wp-content/themes and then run:

ln -s ../generated-theme-slug/theme generated-theme
Code language: plaintext (plaintext)

Working with Tailwind

Generally you’ll want to be watching your theme for changes and regenerating your style.css file automatically:

npm run watch
Code language: plaintext (plaintext)

The watch command will run continuously in the background, keeping things up-to-date.

Unlike the watch command, the dev command from earlier creates a one-off development build and doesn’t update as you make changes.

Before deployment, you’ll want to create a production build:

npm run prod
Code language: plaintext (plaintext)

If you’re using Tailwind for the first time, Tailwind’s documentation is extremely good, and they also have some excellent screencasts to get you started.


Now with built-in theme.json support, _tw includes a basic theme.json file in its theme folder. The color and width values from that file are automatically made available to Tailwind via a Tailwind plugin.

This means the top-level colors in theme.json can be used in Tailwind (with classes like bg-primary or text-primary), and the values for contentSize and wideSize are available for setting max-width with either max-w-content or max-w-wide.

Tailwind Typography

To support Tailwind Typography, _tw uses a fork of Tailwind Typography that adds support for the WordPress block editor while also automatically applying Tailwind Typography’s h1 styles to post titles regardless of their heading level. (This is most relevant on archive pages, where titles will be h2 elements.)

A selection of Tailwind Typography’s configuration options are included in a separate tailwind-typography.config.js file, with a number of comments explaining the rationale for what was included and why changes were made.

Tailwind plugins

Tailwind’s first-party plugins are automatically installed when you run npm install, but they won’t be active until you uncomment the appropriate line or lines in the plugins block of your tailwind.config.js file.

Working with Alpine.js

Once you start using Tailwind, you may find yourself wanting a similar approach to JavaScript. Alpine.js provides just that, and is enqueued automatically with _tw. Head to the Alpine.js GitHub repository for the basics; after that, Laracasts has an excellent (and free) course called Alpine.js Essentials to get you started.

If you don’t want to use Alpine.js, simply remove or comment out the following line:

wp_enqueue_script( '_tw-alpine', get_template_directory_uri() . '/js/alpine.js', array(), '3.x.x', true );
Code language: PHP (php)

(Please note that the script handle and version number may be different in your _tw download.)

Using Browsersync

Because your development environment may have its own approach to Browsersync-like functionality, Browsersync is not included by default. You can install it as follows (in the same place you ran npm install earlier):

npm install browser-sync --save-dev
Code language: plaintext (plaintext)

Assuming a development environment like VVV, you can use Browsersync’s proxy mode with the local .test domain by adding the following line to the scripts section of your package.json file alongside the other watch:* commands:

"watch:browser-sync": "browser-sync start --proxy \"development-website.test\" --files \"theme\" --no-inject-changes",
Code language: plaintext (plaintext)

Deploying to production

To package your theme as a zip archive, you can use the bundle command:

npm run bundle
Code language: plaintext (plaintext)

This command will first execute npm run prod and then create a zip archive from your theme folder, in a zip file named using your theme slug.

The resulting theme archive can be uploaded directly to a WordPress site. Since WordPress 5.5, uploading a theme that has already been installed will result in an option to overwrite the existing theme, providing a viable path for quick deployments.

If you’d like to deploy from the command line, Capistrano is a great solution for command-line deployment of WordPress themes.

Have questions?

Please send a message to @gregsvn on Twitter, and I’ll do my best to help!