Divine

The Standalone Runtime

View as Markdown

The standalone runtime is the part of Divine that an exported theme carries with it so it can run without the plugin. It lives at src/Runtime in the Divine source tree, and export copies that whole surface into the deliverable as divine-runtime/. Nothing else from Divine goes along: no admin app, no worktree services, no workspace REST. The runtime is the minimum a finished theme needs to behave the way it did while you were building it.

Why A Separate Runtime Surface

Divine is two things wearing one codebase: a build environment and a runtime. The build environment is large, with workspaces, previews, review, and a control plane. None of that belongs on a client’s site. But the behavior a theme depends on at render time, Blockstudio block loading, file-based pages, media markup, Tailwind composition, and performance toggles, has to keep working after the theme leaves Divine.

Keeping the runtime as its own namespace under src/Runtime makes that split clean. Export bundles exactly this surface and nothing more, and the bundled copy autoloads only its own namespace, so a client site never loads a single line of Divine’s control plane.

Boot Path

An exported theme’s functions.php requires divine-runtime/src/Runtime/theme-bootstrap.php. That bootstrap is deliberately small. It returns immediately if WordPress is not loaded, defines DIVINE_RUNTIME_PATH from the bundled location, and registers an autoloader that only resolves the Divine\Runtime\ namespace. A class outside that namespace is simply ignored, which is what keeps Harness, admin, and workspace code from ever loading in a standalone theme.

The bootstrap then requires Bootstrap.php and calls Divine\Runtime\Bootstrap::boot(). Boot runs once, guarded against re-entry, and does the following:

  1. Primes and boots the bundled WordPress runtime, loading the scoped Blockstudio autoloader if its Build class is not already present.
  2. Loads the media and Tailwind template helper files if they exist.
  3. Registers the three runtime services.

The three services it registers are the whole runtime feature set:

Service Responsibility
BlockstudioThemeRuntime Wires the bundled Blockstudio build to the theme’s blocks/, pages/, and patterns/ conventions.
PerformanceRuntime Applies divine.json performance behavior such as cleanup toggles, link preloading, and prerendering.
MediaRuntime Provides the lazy and eager media markup helpers used in templates.

Bundled Blockstudio, Scoped

Blockstudio is bundled into the runtime, but it is scoped under the Divine\Lib namespace rather than shipped as the normal plugin. The scoping matters: a client site might already run its own Blockstudio plugin at its own version, and an unscoped bundled copy would collide with it. Because Divine’s copy lives under Divine\Lib, the two never see each other. The exported theme uses its bundled, scoped engine no matter what else is installed.

TailwindPHP, Blockstudio’s class-composition engine, is scoped one level deeper under Divine\Lib\BlockstudioVendor\TailwindPHP for the same reason. The provenance manifest records the bundled Blockstudio version and its GPL-2.0-or-later license against Divine’s own AGPL-3.0-or-later license, and THIRD-PARTY.md carries the matching notice.

Tailwind Helpers

Themes compose Tailwind classes through two helpers the runtime defines, dv_tw_merge() and dv_tw_variants(). Use them directly in templates; do not write theme-local class-composition wrappers around them.

$class = dv_tw_merge( 'px-4 py-2', $is_active ? 'bg-black text-white' : 'bg-white' );

$button = dv_tw_variants( array(
	'base'     => 'inline-flex items-center rounded',
	'variants' => array(
		'size' => array( 'sm' => 'h-8 px-3', 'lg' => 'h-11 px-6' ),
	),
) );
echo $button( array( 'size' => 'lg' ) );

Both helpers resolve the scoped TailwindPHP engine at runtime. They look up the Divine\Lib\BlockstudioVendor\TailwindPHP callables, loading the scoped autoload on first use, and use them for real merge and variant behavior when present. If the scoped engine cannot be resolved, the helpers fall back to a plain class-join and a CVA-style variant composer, so a template never fatals just because the engine is unavailable.

Media Metadata

The runtime includes Divine\Runtime\Media\MediaMetadataBuilder so exported themes can keep assets/media.json fresh without the Divine plugin. Call write() from WordPress after changing theme images:

( new \Divine\Runtime\Media\MediaMetadataBuilder() )->write( get_stylesheet_directory(), true );

The manifest is read by divine_media_image() for width and height attributes. build() returns the same deterministic manifest array for themes that want to write the file themselves, and MediaMetadata::reset() is available when a theme rebuilds the file manually in the same request.

Runtime Config Overrides

runtime-config.php reads a few environment variables and promotes them to constants, but only when the matching constant is not already defined. This lets a host or deployment override runtime behavior without editing theme files, while still letting explicit constants win.

Constant Source env var Effect
DIVINE_VERSION Defaults to the bundled runtime version when not already defined.
DIVINE_RUNTIME_PUBLIC_URL DIVINE_RUNTIME_PUBLIC_URL Sets the public base URL the runtime uses to reference its bundled assets, with a trailing slash trimmed.
DIVINE_WP_LOAD_PATH DIVINE_WP_LOAD_PATH Points the runtime at a specific wp-load.php when WordPress is not in a standard location.

Each value is only adopted when the environment variable is a non-empty string and the constant is still undefined, so defining the constant earlier always takes precedence over the environment.

Runtime And Plugin Together

On a site that does run the Divine plugin, the plugin boots this same runtime for the active theme, so a theme managed inside Divine does not need its own bundled copy. The bundled divine-runtime/ only exists to make a theme standalone. When you upgrade Divine and want a standalone install to pick up runtime changes, re-export the theme; that refreshes the embedded divine-runtime/ directory and its provenance record.