PHPackages                             dennismenken/scratchstart-theme - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. dennismenken/scratchstart-theme

ActiveWordpress-theme[Utility &amp; Helpers](/categories/utility)

dennismenken/scratchstart-theme
===============================

A bare-bones, dependency-free WordPress starter theme. Ships without own CSS or JavaScript so page builders such as Elementor stay in full control and the site stays lightning fast.

v2.0.0(1mo ago)00WTFPLPHPPHP &gt;=8.4CI passing

Since Apr 15Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/dennismenken/scratchstart-theme)[ Packagist](https://packagist.org/packages/dennismenken/scratchstart-theme)[ Docs](https://github.com/dennismenken/scratchstart-theme)[ RSS](/packages/dennismenken-scratchstart-theme/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (3)Versions (2)Used By (0)

ScratchStart Theme
==================

[](#scratchstart-theme)

A bare-bones, dependency-free WordPress starter theme. Ships without custom CSS, JavaScript or opinionated markup so page builders such as Elementor stay in full control and the site stays lightning fast.

Why
---

[](#why)

Most "minimal" WordPress themes still ship a stylesheet, header/footer markup, default post titles and a 404 template. When the real rendering is done by a page builder all of that becomes dead weight or, worse, fights the builder (double H1, doubled headers, leftover sidebars). ScratchStart goes further than Hello Elementor: by default the theme renders **nothing** beyond the document skeleton and a single `` wrapper holding `the_content()`. Header, footer, post title, post meta, comments, sidebar and the archive loop are opt-in via filters.

Features
--------

[](#features)

- No own CSS, no own JavaScript — builders such as Elementor or Bricks own the frontend.
- No theme-rendered chrome by default — ``, ``, post title, post meta, sidebar, comments and the archive loop are opt-in via single-line filters.
- Optional WordPress core cleanup (disable emojis / wp-embed JS / block-library CSS / RSD/wlw/generator/REST/shortlink head links), all opt-in or via a single `scratchstart_lightning_mode` master switch.
- No `404.php`: WordPress falls back to `index.php` so a builder's "Not Found" template can take over.
- Clean, escaped, translation-ready template files.
- `wp_body_open()` hook fired in the right place, skip-link and accessible `` available on demand.
- Block-editor friendly: `responsive-embeds`, `post-thumbnails`, `html5`, `title-tag`, `automatic-feed-links`.
- Composer-installable as a `wordpress-theme` package.
- Automated GitHub Release builds a ready-to-install ZIP.

Requirements
------------

[](#requirements)

- WordPress 6.4 or newer (tested up to 6.9)
- PHP 8.4 or newer

Installation
------------

[](#installation)

### Option A — ZIP from GitHub Releases

[](#option-a--zip-from-github-releases)

1. Grab `scratchstart.zip` from the latest [GitHub Release](https://github.com/dennismenken/scratchstart-theme/releases).
2. In WordPress admin: *Appearance → Themes → Add New → Upload Theme*.
3. Upload the ZIP and activate.

### Option B — Composer (Bedrock, composer-managed WP, etc.)

[](#option-b--composer-bedrock-composer-managed-wp-etc)

```
composer require dennismenken/scratchstart-theme
```

`composer/installers` places the theme under `wp-content/themes/scratchstart/`. If the repository is not on Packagist yet, add it as a VCS repository:

```
{
  "repositories": [
    { "type": "vcs", "url": "https://github.com/dennismenken/scratchstart-theme" }
  ]
}
```

### Option C — Clone for development

[](#option-c--clone-for-development)

```
cd wp-content/themes
git clone https://github.com/dennismenken/scratchstart-theme.git scratchstart
```

Customization
-------------

[](#customization)

### Opt-in chrome

[](#opt-in-chrome)

The theme renders nothing besides the document skeleton and `` by default. Enable any chrome part you actually want from a child theme, a mu-plugin or even a snippet plugin:

```
add_filter('scratchstart_render_skip_link',    '__return_true');
add_filter('scratchstart_render_header',       '__return_true');
add_filter('scratchstart_render_footer',       '__return_true');
add_filter('scratchstart_render_post_title',   '__return_true');
add_filter('scratchstart_render_post_meta',    '__return_true');
add_filter('scratchstart_render_comments',     '__return_true');
add_filter('scratchstart_render_sidebar',      '__return_true');
add_filter('scratchstart_render_archive_loop', '__return_true');
```

`scratchstart_render_header` and `scratchstart_render_footer` additionally require an assigned menu (`Header Menu` / `Footer Menu` under *Appearance → Menus*) before any markup is emitted. The sidebar opt-in also requires at least one widget in the `Main Sidebar` area.

### Optional WordPress core cleanup

[](#optional-wordpress-core-cleanup)

WordPress core itself injects a few things that page-builder workflows rarely need (emoji detection script, oEmbed JS, default block-library CSS, RSD/wlwmanifest/generator/REST/shortlink links). Each is opt-in:

```
add_filter('scratchstart_disable_emojis',            '__return_true');
add_filter('scratchstart_disable_embed_script',      '__return_true');
add_filter('scratchstart_disable_block_library_css', '__return_true');
add_filter('scratchstart_clean_head',                '__return_true');
```

Or flip all four at once:

```
add_filter('scratchstart_lightning_mode', '__return_true');
```

`scratchstart_disable_block_library_css` removes both the classic block-library CSS and the modern `global-styles` / `classic-theme-styles` handles. Re-enable on a per-page basis if a single post relies on Gutenberg blocks.

`scratchstart_disable_emojis` also removes the emoji detection script in the admin (matches the de-facto behaviour of "Disable Emojis"-style plugins) so the editor doesn't ship the script either.

`scratchstart_clean_head` removes both the `wp_head` markup output and the matching HTTP `Link:` headers (REST, shortlink) emitted on `template_redirect`.

### Forking

[](#forking)

Fork or clone, then search-and-replace the slug `scratchstart` and the text domain across the codebase with your own theme name. The theme deliberately avoids enqueueing anything — add a `wp_enqueue_style` call in `functions.php` only if you actually ship styles.

Development
-----------

[](#development)

Install dev dependencies:

```
composer install
```

Run static analysis (PHPStan level 6, with WordPress stubs via `szepeviktor/phpstan-wordpress`):

```
composer analyse
```

Run a quick PHP syntax sweep over every template:

```
composer lint
```

CI runs both on every push to `main` and on every pull request via `.github/workflows/ci.yml`.

Release process (maintainers)
-----------------------------

[](#release-process-maintainers)

1. Bump the `Version:` header in `style.css`.
2. Commit on `main`.
3. Tag and push: ```
    git tag v2.0.0
    git push origin v2.0.0
    ```
4. The `Release` GitHub Actions workflow verifies that the tag matches `style.css`, lints every PHP file, builds `scratchstart.zip` and attaches it to an auto-generated GitHub Release. Versions containing a hyphen (e.g. `v2.1.0-rc1`) are published as prereleases.

A manual `workflow_dispatch` run builds the ZIP as a workflow artifact without creating a release — useful for smoke-testing changes.

License
-------

[](#license)

[WTFPL — Do What The F\*ck You Want To Public License](http://www.wtfpl.net/).

Credits
-------

[](#credits)

- [Dennis Menken](https://devyard.de/)

Changelog
---------

[](#changelog)

### 2.0.0

[](#200)

- **Page-builder-first by default** (breaking vs. 1.x): every chrome part – ``, ``, post title, post meta, comments, sidebar, archive loop, skip-link – is opt-in via `scratchstart_render_*` filters. Default theme output is just ``, ``, body skeleton with `wp_head` / `wp_body_open` / `wp_footer`, and `` containing `the_content()`.
- Optional WordPress core cleanup filters: `scratchstart_disable_emojis`, `scratchstart_disable_embed_script`, `scratchstart_disable_block_library_css`, `scratchstart_clean_head` (plus `scratchstart_lightning_mode` master switch). All default off.
- Bumped minimum PHP to 8.4. Added PHPStan (level 6) static analysis with `szepeviktor/phpstan-wordpress` stubs and a CI workflow (`.github/workflows/ci.yml`) that runs on every push to `main` and on every PR.
- Removed `404.php` so WordPress falls back to `index.php` and lets a builder's "Not Found" template take over via `template_include`.
- Zero-CSS / zero-JS posture: theme no longer enqueues `style.css`.
- Hardened i18n: escaped output, consistent `scratchstart` text domain, fixed `your_theme` typo, `wp_kses` allowlist for translated HTML.
- Modernised `functions.php`: consolidated `after_setup_theme` callback, `load_theme_textdomain`, `automatic-feed-links`, `responsive-embeds`, widened `html5` support.
- `defined('ABSPATH') || exit` guards on every template.
- Sidebar template additionally collapses when no widgets are active even if opted in.
- Navigation menus require an assigned menu before emitting markup; no `wp_page_menu` leak.
- `composer.json` for installation as a `wordpress-theme` Composer package.
- GitHub Actions workflow publishes `scratchstart.zip` on tag pushes.
- Theme metadata refresh (`Requires at least`, `Tested up to`, `Requires PHP`, correct `Author URI`).

### 1.0.0

[](#100)

- Initial release.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance89

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

55d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d4ac4093a1ddd76cd59b8da57b92ddb789d4d60b02330835b04499fd84fc002?d=identicon)[dennismenken](/maintainers/dennismenken)

---

Top Contributors

[![dennismenken](https://avatars.githubusercontent.com/u/7050584?v=4)](https://github.com/dennismenken "dennismenken (9 commits)")

---

Tags

wordpressminimalelementorwordpress-themepage builderblankstarter theme

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/dennismenken-scratchstart-theme/health.svg)

```
[![Health](https://phpackages.com/badges/dennismenken-scratchstart-theme/health.svg)](https://phpackages.com/packages/dennismenken-scratchstart-theme)
```

###  Alternatives

[roots/bedrock

WordPress boilerplate with Composer, easier configuration, and an improved folder structure

6.5k456.5k2](/packages/roots-bedrock)[helsingborg-stad/municipio

A bootstrap theme for creating municipality sites.

4028.3k10](/packages/helsingborg-stad-municipio)[roots/wp-stage-switcher

WordPress plugin that allows you to switch between different environments from the admin bar

382458.3k3](/packages/roots-wp-stage-switcher)[vinkla/wordplate

The WordPlate boilerplate

2.2k5.3k](/packages/vinkla-wordplate)[freemius/wordpress-sdk

Freemius WordPress SDK

304125.8k6](/packages/freemius-wordpress-sdk)[justcoded/wordpress-theme-boilerplate

WordPress theme boilerplate with better code structure and OOP support.

563.9k1](/packages/justcoded-wordpress-theme-boilerplate)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
