PHPackages                             hudsxn/canvas - 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. [API Development](/categories/api)
4. /
5. hudsxn/canvas

ActiveLibrary[API Development](/categories/api)

hudsxn/canvas
=============

A simple page builder API that is agnostic of frameworks, and can be used for CSR or SSR

v1.0.0(4mo ago)04MITPHP

Since Jan 4Pushed 4mo agoCompare

[ Source](https://github.com/hudsxncom/canvas)[ Packagist](https://packagist.org/packages/hudsxn/canvas)[ RSS](/packages/hudsxn-canvas/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

Canvas Framework
================

[](#canvas-framework)

A lightweight, performant PHP framework for building server-rendered and hybrid web applications with a focus on flexibility, security, and developer experience.

Overview
--------

[](#overview)

Canvas provides a structured approach to building web pages through a tree-based component system, decoupled rendering architecture, and comprehensive response handling. It solves common problems in modern PHP web development while maintaining simplicity and performance.

Core Problems Solved
--------------------

[](#core-problems-solved)

### 1. Rendering Flexibility

[](#1-rendering-flexibility)

Traditional PHP frameworks often tightly couple your application logic to a specific templating engine. Canvas solves this by providing a renderer contract that allows you to choose your preferred rendering approach:

- **Server-side templating**: Use Blade, Twig, or plain PHP
- **Single Page Applications**: Generate JSON for React, Vue, or Angular
- **Hybrid approaches**: Server-side rendering with client-side hydration
- **Static site generation**: Pre-render to HTML files

Switch between rendering strategies without changing your application code. Simply swap the renderer implementation.

### 2. Performance Optimization

[](#2-performance-optimization)

Canvas includes several performance-critical features:

**Array-Based String Building**Instead of using string concatenation (which creates new string buffers on each operation), Canvas uses numerically-indexed arrays for HTML generation. This approach is significantly faster for large HTML outputs:

```
// Slow: Creates new string buffer each time
$html .= '';
$html .= $content;
$html .= '';

// Fast: O(1) array append operations
$sourceCode[] = '';
$sourceCode[] = $content;
$sourceCode[] = '';
// Join once at the end: implode('', $sourceCode)
```

**Automatic Gzip Compression**Built-in content negotiation and gzip compression can reduce HTML payload sizes by 70-90%, significantly improving page load times. Compression level is configurable from 1 (fastest) to 9 (maximum compression).

**Bitwise Flags**Page configuration flags (caching, indexing, security) use bitwise operations instead of individual boolean properties, reducing memory usage and providing faster flag checks.

### 3. Security by Default

[](#3-security-by-default)

Canvas makes it easy to implement security best practices:

- **Content Security Policy**: Fluent API for configuring CSP directives
- **Automatic Security Headers**: X-Frame-Options, X-Content-Type-Options, HSTS
- **HTTPS Enforcement**: Built-in HTTPS redirect support
- **XSS Protection**: CSP helpers with sensible defaults

Configure comprehensive security policies in a few lines:

```
$page->enableCsp()
     ->allowScriptFrom("'self'", 'https://cdn.example.com')
     ->allowStyleFrom("'self'")
     ->blockAllMixed()
     ->forceHttps();
```

### 4. SEO and Metadata Management

[](#4-seo-and-metadata-management)

Centralized management of document metadata, Open Graph tags, Twitter Cards, and search engine directives:

```
$page->setTitle('Page Title')
     ->setMeta('description', 'Page description')
     ->setSeo('og:image', 'https://example.com/image.jpg')
     ->setSeo('twitter:card', 'summary_large_image')
     ->noIndex(); // Staging environment
```

### 5. Separation of Concerns

[](#5-separation-of-concerns)

Canvas enforces clean architecture through separation:

- **Node**: Structure and hierarchy (the "what")
- **Canvas**: Root container with template information (the "where")
- **Page**: Document metadata and policies (the "metadata")
- **Renderer**: Presentation logic (the "how")
- **Response**: HTTP delivery (the "transport")

This separation makes testing easier, code more maintainable, and allows different parts of your application to evolve independently.

Architecture
------------

[](#architecture)

### Node System

[](#node-system)

The Node class provides a flexible tree structure for representing UI components or document elements. Each node contains:

- Type identifier (component name)
- Arbitrary properties (JSON-serializable)
- Child nodes
- Parent reference

Nodes can be searched, traversed, and manipulated programmatically:

```
$root = new Node('div', ['class' => 'container']);
$root->addChild(new Node('h1', ['text' => 'Welcome']))
     ->addChild(new Node('p', ['text' => 'Content']));

// Search the tree
$button = $root->getChildByName('Button');
$primary = $root->getChildWhereProp('variant', 'primary');
```

### Canvas (Root Container)

[](#canvas-root-container)

Canvas extends Node to represent the complete document, adding template information:

```
$canvas = new Canvas('layouts/app', [
    'title' => 'My Page',
    'theme' => 'dark'
]);

// Change templates dynamically
if ($isMobile) {
    $canvas->setTemplate('layouts/mobile');
}
```

### Page (Document Configuration)

[](#page-document-configuration)

Page combines a Canvas with complete document metadata and behavioral rules:

```
$page = new Page($canvas);
$page->setTitle('Welcome')
     ->setLocale('en-US')
     ->setCharset('UTF-8')
     ->enableCsp()
     ->forceHttps()
     ->noCache();
```

### Renderer (Pluggable Rendering)

[](#renderer-pluggable-rendering)

Implement the `CanvasPageRenderer` interface to define how pages are rendered:

```
class BladeRenderer implements CanvasPageRenderer
{
    public function generateHtml(Page $page, array &$sourceCode): void
    {
        $canvas = $page->getCanvas();
        $html = view($canvas->getTemplate(), [
            'page' => $page,
            'canvas' => $canvas
        ])->render();

        $sourceCode[] = $html;
    }
}
```

### Response (HTTP Delivery)

[](#response-http-delivery)

Response handles the complete HTTP response lifecycle:

```
$response = new Response($renderer, $page);
$response->setCompressionLevel(6)
         ->setStatusCode(200)
         ->addHeader('X-Custom-Header', 'value')
         ->send();
```

Performance Features
--------------------

[](#performance-features)

### Efficient String Building

[](#efficient-string-building)

Using array-based string building avoids the performance penalty of repeated string concatenation. For large HTML documents, this can provide significant performance improvements.

### Configurable Compression

[](#configurable-compression)

Gzip compression with configurable levels (1-9) allows you to balance compression ratio against CPU usage based on your needs:

- Level 1-3: Fast compression for dynamic content
- Level 6: Balanced (default)
- Level 9: Maximum compression for static assets

### Bitwise Flag Operations

[](#bitwise-flag-operations)

Page flags use bitwise operations for efficient storage and fast checks:

```
// Set multiple flags efficiently
$page->noIndex()->noFollow()->noCache();

// Fast flag checking internally
if (($flags & Page::NO_CACHE) === Page::NO_CACHE) {
    // Apply no-cache headers
}
```

Security Features
-----------------

[](#security-features)

### Content Security Policy

[](#content-security-policy)

Fluent API for building CSP directives:

```
$page->enableCsp()
     ->allowScriptFrom("'self'", 'https://cdn.jsdelivr.net')
     ->allowStyleFrom("'self'", "'unsafe-inline'")
     ->allowImageFrom('https:', 'data:')
     ->allowConnectTo("'self'", 'https://api.example.com')
     ->blockAllMixed()
     ->requireSri();
```

### Automatic Security Headers

[](#automatic-security-headers)

Response automatically generates security headers:

- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: SAMEORIGIN`
- `X-XSS-Protection: 1; mode=block`
- `Referrer-Policy: strict-origin-when-cross-origin`
- `Strict-Transport-Security` (when HTTPS is enforced)

### HTTPS Enforcement

[](#https-enforcement)

Built-in support for forcing HTTPS connections:

```
$page->forceHttps();
// Generates: Strict-Transport-Security: max-age=31536000; includeSubDomains
```

Use Cases
---------

[](#use-cases)

### Traditional Server-Rendered Applications

[](#traditional-server-rendered-applications)

Use Canvas with your preferred template engine (Blade, Twig, plain PHP) for traditional server-side rendering with enhanced performance and security features.

### Single Page Applications

[](#single-page-applications)

Canvas includes a built-in `SinglePageApplicationRenderer` for SPAs with full control over assets and state injection:

```
use Hudsxn\Canvas\Renderers\SinglePageApplicationRenderer;

$renderer = new SinglePageApplicationRenderer();
$renderer->setJsUrl('/dist/app.js')
         ->setCssUrl('/dist/app.css')
         ->setMountElement('app')
         ->setStateVariable('__PAGE_STATE__');

$page = new Page($canvas);
$page->setTitle('My SPA')
     ->setMeta('description', 'A React application')
     ->enableCsp()
     ->allowScriptFrom("'self'");

$response = new Response($renderer, $page);
$response->send();
```

The SPA renderer generates a minimal HTML shell with:

- Automatic viewport configuration for mobile optimization
- CSP-compliant nonce-based inline script injection
- Configurable mount points and state variables
- Support for single or multiple JS/CSS bundles (vendor splitting)
- Complete page state serialized to JSON for client-side hydration

**Multiple Asset Support:**

```
// Vendor + App splitting
$renderer->setJsUrls([
    '/dist/vendor.js',
    '/dist/app.js'
])->setCssUrls([
    'https://fonts.googleapis.com/css2?family=Inter',
    '/dist/app.css'
]);
```

### Hybrid Applications

[](#hybrid-applications)

Combine server-side rendering with client-side hydration for optimal performance and SEO:

1. Server renders initial HTML
2. Canvas state serialized to JSON
3. Client-side framework hydrates from JSON

### Static Site Generation

[](#static-site-generation)

Pre-render pages to static HTML files:

```
$html = $response->render();
file_put_contents("dist/page-{$id}.html", $html);
```

Getting Started
---------------

[](#getting-started)

### Installation

[](#installation)

```
composer require hudsxn/canvas
```

### Basic Example

[](#basic-example)

```
use Hudsxn\Canvas\Objects\{Canvas, Page, Node};
use Hudsxn\Canvas\Response;

// Build the tree
$canvas = new Canvas('layouts/default');
$canvas->addChild(new Node('Header', ['logo' => 'logo.png']))
       ->addChild(new Node('Main', ['content' => 'Welcome!']))
       ->addChild(new Node('Footer'));

// Configure the page
$page = new Page($canvas);
$page->setTitle('Welcome to My Site')
     ->setMeta('description', 'A great website')
     ->enableCsp()
     ->allowScriptFrom("'self'")
     ->forceHttps();

// Render and send
$renderer = new MyRenderer();
$response = new Response($renderer, $page);
$response->send();
```

### Quick Start: Single Page Application

[](#quick-start-single-page-application)

Canvas includes a production-ready SPA renderer:

```
use Hudsxn\Canvas\Objects\{Canvas, Page};
use Hudsxn\Canvas\Renderers\SinglePageApplicationRenderer;
use Hudsxn\Canvas\Response;

// Create your page structure
$canvas = new Canvas('spa-app');
$canvas->addChild(new Node('Dashboard', ['userId' => 123]));

$page = new Page($canvas);
$page->setTitle('My React App')
     ->setMeta('viewport', 'width=device-width, initial-scale=1')
     ->enableCsp()
     ->allowScriptFrom("'self'", 'https://cdn.example.com')
     ->allowStyleFrom("'self'");

// Configure the SPA renderer
$renderer = new SinglePageApplicationRenderer();
$renderer->setJsUrl('/dist/app.js')
         ->setCssUrl('/dist/app.css');

// Send the response
$response = new Response($renderer, $page);
$response->send();
```

The client-side app can access the state:

```
// Your React/Vue/Angular app
const state = window.__PAGE_STATE__;
console.log(state.canvas); // Full Canvas tree
console.log(state.title);  // "My React App"
```

### Implementing a Renderer

[](#implementing-a-renderer)

```
use Hudsxn\Canvas\Contracts\CanvasPageRenderer;
use Hudsxn\Canvas\Objects\Page;

class MyRenderer implements CanvasPageRenderer
{
    public function generateHtml(Page $page, array &$sourceCode): void
    {
        $canvas = $page->getCanvas();

        $sourceCode[] = '';
        $sourceCode[] = '';
        $sourceCode[] = '';
        $sourceCode[] = '';
        $sourceCode[] = '' . htmlspecialchars($page->getTitle()) . '';

        // Render meta tags
        foreach ($page->getMetaTags() as $name => $content) {
            $sourceCode[] = '';
        }

        $sourceCode[] = '';
        $sourceCode[] = '';

        // Render canvas children
        foreach ($canvas->getChildren() as $node) {
            $sourceCode[] = $this->renderNode($node);
        }

        $sourceCode[] = '';
        $sourceCode[] = '';
    }

    private function renderNode($node): string
    {
        // Your component rendering logic
        return '' . $node->getName() . '';
    }
}
```

Design Philosophy
-----------------

[](#design-philosophy)

Canvas is built on several key principles:

**Flexibility Over Convention**: Choose your own rendering approach, template engine, and architecture. Canvas provides structure without imposing rigid conventions.

**Performance by Default**: Built-in optimizations like array-based string building and gzip compression mean you get good performance without extra effort.

**Security by Design**: Making security features easy to use encourages their adoption. CSP configuration should be as simple as method chaining.

**Separation of Concerns**: Clear boundaries between structure (Node), metadata (Page), rendering (Renderer), and transport (Response) make code more maintainable and testable.

**Progressive Enhancement**: Start simple and add features as needed. Use basic rendering or add compression, security headers, and advanced CSP as your application grows.

**Batteries Included**: While remaining flexible, Canvas includes a production-ready `SinglePageApplicationRenderer` so you can start building immediately without boilerplate.

Bundled Renderer
----------------

[](#bundled-renderer)

### SinglePageApplicationRenderer

[](#singlepageapplicationrenderer)

A production-ready renderer for React, Vue, Angular, and other client-side frameworks.

**Features:**

- CSP-compliant nonce-based script injection
- Automatic viewport configuration
- Support for single or multiple JS/CSS bundles
- Configurable mount points and state variables
- SEO-friendly meta tag generation
- Automatic state serialization

**Configuration Options:**

```
$renderer = new SinglePageApplicationRenderer();

// Asset configuration
$renderer->setJsUrl('/dist/app.js');              // Single JS file
$renderer->setJsUrls([...]);                      // Multiple JS files
$renderer->setCssUrl('/dist/app.css');            // Single CSS file
$renderer->setCssUrls([...]);                     // Multiple CSS files

// Customization
$renderer->setMountElement('root');               // Change mount point
$renderer->setStateVariable('INITIAL_STATE');     // Change state variable
$renderer->includeViewport(false);                // Disable default viewport
```

**Generated HTML Structure:**

```
>

    My App

        window.__PAGE_STATE__ = {
            "title": "My App",
            "canvas": {...},
            "meta": {...}
        };

```

**Advanced Usage:**

```
// Production build with vendor splitting
$renderer = new SinglePageApplicationRenderer();
$renderer->setJsUrls([
    'https://cdn.example.com/vendor.js',
    'https://cdn.example.com/app.js'
])->setCssUrls([
    'https://fonts.googleapis.com/css2?family=Inter',
    'https://cdn.example.com/app.css'
])->setMountElement('react-root')
  ->setStateVariable('APP_DATA');

// Configure CSP for external resources
$page->enableCsp()
     ->allowScriptFrom("'self'", 'https://cdn.example.com')
     ->allowStyleFrom("'self'", 'https://fonts.googleapis.com')
     ->allowFontFrom('https://fonts.gstatic.com');
```

License
-------

[](#license)

MIT License - see LICENSE file for details.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance75

Regular maintenance activity

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 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

134d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a1c414ede123b1a90a206934071021be75f144fa79c077ded9919e9c0852a53d?d=identicon)[Hudsxn](/maintainers/Hudsxn)

---

Top Contributors

[![hudson1998x](https://avatars.githubusercontent.com/u/22916228?v=4)](https://github.com/hudson1998x "hudson1998x (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hudsxn-canvas/health.svg)

```
[![Health](https://phpackages.com/badges/hudsxn-canvas/health.svg)](https://phpackages.com/packages/hudsxn-canvas)
```

###  Alternatives

[stripe/stripe-php

Stripe PHP Library

4.0k143.3M480](/packages/stripe-stripe-php)[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M272](/packages/twilio-sdk)[facebook/php-business-sdk

PHP SDK for Facebook Business

90821.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

74513.7M114](/packages/meilisearch-meilisearch-php)[google/gax

Google API Core for PHP

265103.1M454](/packages/google-gax)[google/common-protos

Google API Common Protos for PHP

173103.7M50](/packages/google-common-protos)

PHPackages © 2026

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