npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

irgen-ext-php-shared-hosting

v0.1.2

Published

irgen extension for generating PHP-based blogging system deployable to shared hosting

Readme

irgen-ext-php-shared-hosting

A specialized irgen extension that generates a Hybrid App Platform for Shared Hosting. It combines a premium Blogging System with an Internal App Engine (MySQL + PHP REST API) for your React applications.

Note: This extension does not introduce a new frontend generator. All UI is compiled by irgen core; the extension only provides backend targets and declarative presets.

Features

  • Hybrid Engine: Supports both a public blog and private internal application logic.
  • Automatic REST API: DSL entity() declarations automatically become secure PHP REST endpoints.
  • MySQL Integration: Built-in PDO-based storage for business data, compatible with standard shared hosting.
  • Zero-Config Backend: Generates a complete, secure PHP 7.4+ application.
  • Premium Aesthetics: Refined blogging templates with modern typography and animations.
  • SEO Ready: Automatic generation of rss.xml and sitemap.xml.
  • Internal App Presets: Use adminPreset for the blog manager and appPreset for your custom apps.
  • Secure: Built-in CSRF protection, Session hardening, and PDO-based SQL injection prevention.

Usage (v0.1.1+)

1. Scaffolding a New Project

Use the irgen init command with the extension to jumpstart a PHP blogging system.

npx irgen init my-blog --ext=irgen-ext-php-shared-hosting --template=php-blog

2. In Your DSL (irgen config)

Import the extension methods to configure your admin panel comfortably.

// app.dsl.ts (Data & Logic)
import { app } from "irgen";

app("MyProject", (t) => {
  t.entity("Ticket", (e) => {
    e.model({ title: "string", status: "string" });
    e.list();
  });
});

// ui.dsl.ts (Frontend Applications)
import { frontend } from "irgen";
import { adminPreset, appPreset } from "irgen-ext-php-shared-hosting"; 

// 1. Admin UI (Managed Blog + Tools)
frontend("admin", (f) => {
  adminPreset({ adminBasePath: "/admin" })(f);
});

// 2. Internal User App (Custom React App)
frontend("portal", (f) => {
  appPreset({ publicBasePath: "/portal" })(f);
});

3. Running the Generator

Point irgen to your main DSL file (which imports any others).

# Generate both targets in one go
npx irgen app.dsl.ts \
  --ext=irgen-ext-php-shared-hosting \
  --targets=frontend,php-shared-hosting \
  --outDir=generated/hybrid

🏗️ Modern Architecture: Multi-DSL (Split DSL)

We recommend splitting your definition into two or more files (e.g., app.dsl.ts and ui.dsl.ts). To make this work, simply import your secondary DSLs into your main entry file:

// app.dsl.ts (Main Entry)
import { app } from "irgen";
import "./ui.dsl.ts"; // <--- Import your UI definitions

app("MyProject", (t) => { ... });

This pattern provides:

  1. Separation of Concerns: Your data models (entity()) and backend configurations stay clean from UI layouts.
  2. Scalability: You can easily add more frontends (e.g., a Mobile App or a Landing Page) without bloating a single file.
  3. Shared Logic: Both the Admin UI and your User Portal will automatically see the same Entity schemas and use the same generated REST API.

Note: The --ext flag tells irgen to load this extension. The --targets flag ensures both the frontend assets and the PHP backend are generated.

When you build the generated frontend (npm run build inside generated/.../frontend), the package.json includes a postbuild hook that copies the admin build into public/<adminBasePath> automatically (default: public/admin/).

When you generate both targets together, the backend emitter reads the adminPreset(...) options from the frontend app metadata. That means siteBasePath, adminBasePath, adminApiBasePath, and other options stay in sync without extra CLI flags.

The generated public/router.php reads config/app.config.php at runtime, so changes to siteBasePath, adminBasePath, and adminApiBasePath are reflected automatically.

Generated Output

generated/
├── app/                  # PHP Application Core (Utils, Entity Logic)
├── config/               # Configuration (manifest, app.config.php)
├── data/                 # Flat-file Store (Posts)
├── public/
│   ├── .htaccess         # Master Routing (Multi-SPA + API)
│   ├── admin/            # React Admin UI
│   ├── portal/           # Custom User WebApp (example)
│   ├── api/              # Generated Entity REST Endpoints
│   ├── admin-api/        # Blog Management API
│   ├── site/             # Public Blog Frontend
│   └── uploads/          # User uploads
└── ...

Admin Routes (v0)

  • /admin/ posts list
  • /admin/posts/new create post
  • /admin/posts/:slug edit markdown (enter slug + markdown)

Admin UI Theming

The preset applies styling.themePack: "admin" so the generated UI uses the admin layout (sidebar + compact headers). It also marks intro components with uiVariant: "header" so page headers render inline instead of cards.

Generated Project README

Each generated project includes README.md with local test and deployment steps.

API Reference

adminPreset(options)

The main entry point. Creates a preset and applies it to your frontend builder.

Options:

| Option | Default | Description | |--------|---------|-------------| | deploymentMode | 'mode-a' | 'mode-a' (Secure, app/ outside public) or 'mode-b' (Single root) | | adminBasePath | '/admin/' | URL path for the Admin UI | | adminApiBasePath | '/admin-api/' | URL path for the PHP API | | siteBasePath | '/site' | Base path for the public static site | | siteBaseUrl | '' | Absolute base URL for canonical/RSS | | siteTagline | '' | Tagline used for meta description | | siteNav | [] | Nav items for public site header | | siteTitle | '' | Title of your blog | | postsDir | 'data/posts' | Where to store markdown files | | db | See below | MySQL configuration (host, name, user, pass) |

appPreset(options)

Preset for consumer-facing React applications. It configures the app to connect to the generated PHP API and sets up correct deployment paths.

Options:

  • publicBasePath: The path where this app is hosted (e.g., /app).

Database Configuration

If your DSL contains entity() definitions, you should provide MySQL credentials in t.meta("php-shared-hosting", { db: { ... } }) or during extension registration.

{
  "host": "localhost",
  "name": "your_db",
  "user": "db_user",
  "pass": "db_pass"
}

Advanced Usage

For granular control, you can split the creation and application:

import { createAdminPreset, applyAdminPreset } from "...";

// 1. Create the Declarative Object
const decl = createAdminPreset({ ... });

// 2. Modify it (e.g. add a custom page)
decl.pages.push({ ... });

// 3. Apply it
frontend("admin", applyAdminPreset(decl));

Deployment

Mode A (Recommended)

Upload public/ folder contents to your hosting's public_html. Place app/, config/, and data/ one level above public_html.

Mode B (Simple)

Upload everything to public_html. The generated .htaccess files will protect your code and data.

REST API + Auth + CORS

Endpoints live under adminApiBasePath (default /admin-api/) and use PHP sessions. Full request/response documentation lives in extensions/php-shared-hosting/docs/REST-API.md.

Quick checks:

  • GET /admin-api/health
  • GET /admin-api/info
  • POST /admin-api/auth/login (form-urlencoded)
  • GET /admin-api/auth/me

Enable CORS (only if your admin UI is hosted on a different origin):

  1. Edit config/app.config.php
  2. Set options.cors.enabled = true
  3. Add your domain to options.cors.allowedOrigins
  • If /admin-api/health returns HTML in local preview, your router is matching /admin before /admin-api. Ensure your router.php checks /admin-api first with a strict prefix match.

Public site root:

  • If you want the public site at /, set siteBasePath: "" in your options. The publisher will write output directly under public/ instead of public/site/.

License

MIT