Fir Theme Framework
Fir is our sophisticated WordPress theme framework built on top of Roots Sage, leveraging modern PHP and JavaScript technologies. Named after the Douglas Fir tree, it features a component-based architecture where individual components are called "Pinecones" - creating a cohesive, nature-themed development ecosystem.
The framework's modular Pinecone system is designed for maximum portability and reusability. Pinecones are self-contained components that can typically be dropped into other Fir-based projects with little to no adjustment, enabling rapid development and consistent functionality across multiple sites.
Architecture Overview
Core Technologies
- Laravel Blade for templating
- Roots Acorn for Laravel-like features in WordPress
- Tailwind CSS v4 with CSS-first configuration
- Vue.js 3 for interactive components
- GSAP for advanced animations
- Vite for lightning-fast build tooling (upgraded from Bud.js)
- ACF Composer for Advanced Custom Fields management
Foundation
Fir extends Roots Sage with a sophisticated component system that bridges traditional WordPress development with cutting-edge frontend technologies, providing a scalable and maintainable architecture for complex WordPress sites.
Pinecone Component System
The heart of Fir's architecture is the Pinecone system - self-contained, reusable components with a standardized structure designed for cross-project portability. Each Pinecone encapsulates all its dependencies, styles, and functionality, making them highly modular building blocks that can be easily shared between different Fir-based websites.
Component Structure
Each Pinecone follows a consistent, portable structure that enables easy transfer between projects:
fir/Pinecones/[ComponentName]/
├── App.vue # Vue.js component (if needed)
├── view.blade.php # Blade template
├── script.js # JavaScript logic (Web Components)
├── admin.css # Admin styling
├── tailwind.js # Component-specific Tailwind config
├── Blocks/[ComponentName].php # ACF Block definition
├── Components/ # Sub-components (if complex)
└── README.md # DocumentationPortability Features:
- Self-contained assets - All styles, scripts, and dependencies included
- Standardized structure - Consistent patterns across all components
- Framework integration - Automatic discovery and registration
- Minimal configuration - Works out-of-the-box in any Fir project
- Version compatibility - Components work across Fir framework versions
Available Pinecones
Layout Components:
- Layout - Main page structure and containers
- Wrap - Content wrapper with spacing controls
- Columns - Flexible column layouts
- Spacer - Vertical spacing control
Content Components:
- Hero - Hero sections with background options
- Heading - Typography with size and style controls
- Paragraph - Text content with formatting
- Markdown - Markdown content processing
- Image - Advanced image display with transformations
Interactive Components:
- Accordion - Expandable content sections
- Form - Contact and submission forms
- Button - Call-to-action buttons with styling
- Drawer - Slide-out navigation panels
- Sticky - Sticky positioned elements
Data Display:
- Cards - Content card layouts
- Table - Data table presentation
- Testimonials - Client testimonial displays
- Bio - Team member profiles
- Callout - Highlighted content blocks
Visual Elements:
- Collage - Image collage layouts
- Panel/Panels - Content panel systems
- Infobox - Information highlight boxes
Innovative Features
Web Components Integration
Each Pinecone uses modern Web Components (Custom Elements) for JavaScript functionality:
class Accordion extends HTMLElement {
constructor(...args) {
const self = super(...args)
self.init()
return self
}
init() {
this.props = this.getInitialProps()
this.resolveElements()
}
getInitialProps() {
// Parse JSON data from template
return JSON.parse(
this.querySelector('script[type="application/json"]').innerText
)
}
}
customElements.define('fir-accordion', Accordion)Vue.js Hybrid Approach
Complex components seamlessly integrate Vue.js for reactive interfaces:
// Form component with Vue integration
initVue() {
let vueWrapper = this.querySelector('[data-vue]')
if(vueWrapper) {
const app = createApp(App)
app.config.globalProperties.$formdata = this.props
app.mount(`#${this.ID}`)
}
}Auto-Discovery System
Components are automatically discovered, registered, and built without manual configuration:
// Automatic discovery and registration
$dirs = glob(get_theme_file_path('/fir/Pinecones/*'), GLOB_ONLYDIR);
foreach ($dirs as $d) {
$name = basename($d);
$class = "Fir\\Pinecones\\" . $name . '\\';
app('AcfComposer')->registerPath($d, $class);
}Development Features
Global Fields System
Sophisticated reusable field configurations for common use cases:
class GlobalFields {
public static function getFields($field, $name = false, $label = false) {
return self::$field($name, $label);
}
private static function animation($name, $label) {
// Complex animation field configuration with:
// - Fade controls
// - Transform options
// - Filter effects
// - Masking reveals
// - Timing and easing
}
}GSAP Animation System
Integrated GSAP animations with intersection observers:
function setupDrawStroke() {
const drawStrokeElements = document.querySelectorAll('[data-animation~="drawStroke"]');
const handleDrawStroke = (entries, observer) => {
entries.forEach(entry => {
let path = entry.target.querySelector('path');
if(entry.isIntersecting) {
gsap.to(path, {duration:3, drawSVG: "0% 100%"});
}
});
}
}Modern Build Pipeline (Vite-Powered)
- Lightning-fast HMR - Instant hot module replacement for development
- Automatic asset discovery - Dynamic discovery and bundling of Pinecone components
- Individual component bundling - Each Pinecone gets its own optimized entry point
- Code splitting - Automatic chunk splitting for better caching and performance
- Tailwind CSS v4 - CSS-first configuration with automatic theme.json generation
- Enhanced WordPress integration - Laravel Vite plugin with WordPress-specific optimizations
Tailwind CSS v4 Integration
Modern CSS-first approach with enhanced WordPress integration:
CSS-First Configuration:
@import "tailwindcss";
@source "../views/";
@source "../../fir/Pinecones/**/*.php";
@source "../../fir/Lib/Utils/Tailwind.php";
@source "../../public/build/assets/safelist.json";Automatic WordPress Integration:
- Theme.json generation - Automatically extracts CSS variables and generates WordPress theme.json
- Block editor sync - Keeps WordPress editor styles in sync with design tokens
- Dynamic safelist - Generates safelist.json for Tailwind purging automatically
Advanced Features:
- Container queries native support
- CSS cascade layers for better specificity control
- Modern CSS features leveraging latest browser capabilities
- Component-specific configurations per Pinecone
- Design token integration with WordPress theme system
Build System Evolution
The Fir framework has evolved through multiple build systems. Choose the appropriate build system based on your project's version and avoid upgrading older projects unnecessarily.
Version Compatibility
Do not upgrade older Fir projects from Bud.js or Laravel Mix to Vite. Each build system is tied to specific framework versions and dependencies. Upgrading can break existing functionality and introduce compatibility issues.
Current: Vite (Latest Versions)
When to Use: New projects, latest Fir framework versions
Primary Configuration (vite.config.js):
export default defineConfig({
base: '/app/themes/fir/public/build/',
plugins: [
tailwindcss(),
vue(),
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
...firPineconeAssets(), // Auto-discovered Pinecone assets
],
refresh: true,
}),
wordpressPlugin(), // WordPress dependency handling
wordpressThemeJson(), // Automatic theme.json generation
firSafelistPlugin(), // Dynamic Tailwind safelist
],
})Development Commands:
# Development with HMR
npm run dev
# Production build with optimization
npm run buildPrevious: Bud.js (Mid-Generation Versions)
When to Use: Existing projects using Bud.js - do not upgrade to Vite
Configuration (bud.config.js):
export default async (bud) => {
bud
.entry('app', ['@scripts/app', '@styles/app'])
.entry('editor', ['@scripts/editor', '@styles/editor'])
.assets(['images'])
.external(['jquery'])
.vue()
.tailwindcss()
.copyDir('fir/assets')
.watch(['resources/views', 'app', 'fir']);
// Auto-discover Pinecone assets
const pinecones = await bud.glob('fir/Pinecones/**/script.js');
pinecones.forEach(pinecone => {
const name = pinecone.split('/')[2];
bud.entry(name.toLowerCase(), [`fir/Pinecones/${name}/script.js`]);
});
}Development Commands:
# Development with file watching
yarn dev
# Production build
yarn build
# Build diagnostics
yarn dr
# Clean build artifacts
yarn cleanLegacy: Laravel Mix (Early Versions)
When to Use: Older Fir projects using Mix - do not upgrade
Configuration (webpack.mix.js):
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.vue({ version: 3 })
.postCss('resources/css/app.css', 'public/css', [
require('tailwindcss'),
require('autoprefixer'),
])
.options({
processCssUrls: false
});
// Auto-discover Pinecone components
const glob = require('glob');
const pinecones = glob.sync('fir/Pinecones/**/script.js');
pinecones.forEach(pinecone => {
const name = pinecone.split('/')[2].toLowerCase();
mix.js(pinecone, `public/js/pinecones/${name}.js`);
});
if (mix.inProduction()) {
mix.version();
}Development Commands:
# Development with file watching
npm run watch
# Production build
npm run production
# Development build
npm run devBuild System Comparison
| Feature | Vite | Bud.js | Laravel Mix |
|---|---|---|---|
| Speed | ⚡ Instant HMR | 🚀 Fast builds | 🐌 Slower webpack |
| Bundle Size | 📦 Optimal | 📦 Good | 📦 Larger |
| Vue.js Support | ✅ Native | ✅ Plugin | ✅ Plugin |
| Tailwind CSS | ✅ v4 Native | ✅ v3 Plugin | ✅ v2/v3 PostCSS |
| WordPress Integration | ✅ Specialized | ✅ Custom | ⚠️ Manual |
| Auto-discovery | ✅ Advanced | ✅ Good | ⚠️ Basic |
| Maintenance | 🔄 Active | 🔄 Stable | ⚠️ Legacy |
Migration Guidelines
Do Not Upgrade Existing Projects
Keep existing projects on their current build system. Each build system has specific dependencies and configurations that are not backwards compatible.
For New Projects:
- Use Vite for all new Fir framework projects
- Leverage the latest Tailwind CSS v4 features
- Take advantage of enhanced WordPress integration
For Existing Projects:
- Bud.js projects: Continue using Bud.js commands and configuration
- Laravel Mix projects: Maintain existing webpack.mix.js setup
- Only upgrade if absolutely necessary and with full testing
Identifying Your Build System:
# Check package.json for build dependencies
cat package.json | grep -E "(vite|bud|mix)"
# Look for configuration files
ls -la | grep -E "(vite.config|bud.config|webpack.mix)"Developer Experience
Enhanced Component Development
- Individual component bundling - Each Pinecone gets its own optimized entry point
- Instant HMR - Changes to CSS, JavaScript, and Vue components reflect immediately
- Automatic asset enqueuing - Laravel Vite plugin handles WordPress asset integration
- Component templates with preview examples
- Automatic block registration in WordPress
- Custom block categories organization
- Live preview capabilities with Vite dev server
Utility System
Rich helper classes for common operations:
- Image transformation utilities
- Animation helpers
- Menu generation
- State management
- Content processing
Progressive Enhancement
Components work without JavaScript but enhance with interactive features when available, ensuring accessibility and performance.
Best Practices
Component Design
- Self-contained - Each Pinecone manages its own assets and dependencies
- Portable - Components can be copied between projects with minimal setup
- Configurable - Extensive field options for customization
- Accessible - Built with accessibility in mind
- Performance-focused - Optimized loading and rendering
- Drop-in ready - Automatic registration and integration in any Fir project
Development Workflow
- Use the auto-discovery system for new components
- Follow the established Pinecone structure for maximum portability
- Leverage global fields for common configurations
- Test components in isolation and integration
- Document component usage and options
- Design components for reuse across multiple projects
- Avoid project-specific hardcoded values or dependencies
Naming Conventions
- Follow the nature theme (Fir → Pinecones)
- Use descriptive, action-oriented component names
- Maintain consistency across similar components
- Consider component grouping and organization
Key Innovations
- Vite-Powered Performance - Lightning-fast builds and HMR with modern ESM-first architecture
- Automatic WordPress Integration - Seamless theme.json generation and block editor synchronization
- Modular Component Portability - Pinecones are designed as drop-in components that work across projects with minimal adjustment
- CSS-First Design Tokens - Tailwind v4 integration with automatic WordPress theme synchronization
- Thematic Consistency - The tree/nature naming convention creates memorable, cohesive branding
- Hybrid Architecture - Seamlessly blends WordPress blocks, Web Components, and Vue.js
- Auto-Discovery - Eliminates manual configuration for component registration and asset bundling
- Global Field Reusability - Sophisticated system for sharing configurations
- Animation Integration - Built-in GSAP with accessible configuration
- Progressive Enhancement - Works everywhere, enhanced where possible
Performance Benefits with Vite
Development Speed
- Instant server start - Cold server start in milliseconds
- Lightning-fast HMR - Changes reflect immediately without full page reload
- Optimized dependency pre-bundling - Dependencies are pre-bundled with esbuild
- Enhanced error reporting - Better error messages and stack traces
Production Optimization
- Smaller bundle sizes - Better tree shaking and dead code elimination
- Code splitting - Automatic chunk splitting for improved caching
- Asset optimization - Built-in minification and compression
- Modern browser targeting - Generates optimized code for current browsers
- Critical CSS extraction - Automatic extraction of critical styles
WordPress-Specific Enhancements
- Asset versioning - Automatic cache busting with content-based hashing
- Dependency tracking - WordPress dependencies tracked automatically in manifest
- Block editor integration - Real-time synchronization with WordPress editor styles
- Theme.json automation - Eliminates manual theme.json maintenance
Fir with Vite represents the cutting edge of WordPress theme development, combining lightning-fast build tooling with sophisticated component architecture. The migration to Vite delivers significant performance improvements for both development and production while maintaining the flexibility and ease-of-use that makes WordPress accessible to content creators and developers alike.