Built by a developer, for developers

PostgreSQL. PHP 8.x. REST API. Plugin system. Theme engine. Readable code, no lock-in.

View on GitHub API Docs

Architecture overview

A clean, well-structured PHP application. No framework magic — just patterns that work.

Database

PostgreSQL with PDO prepared statements everywhere. Active Record pattern for data models. Version-controlled migrations.

Backend

PHP 8.x, MVC-like architecture. Front-controller routing. Clean separation of data, logic, and views.

Frontend

Zero-dependency HTML5 by default. Modern vanilla JavaScript. Bootstrap and Tailwind support also available.

API

Full REST API with key-based authentication, rate limiting, CORS support. 40+ model endpoints with CRUD + actions.

Plugins

Self-contained modules with their own data models, views, admin pages, routes, and scheduled tasks.

Themes

Override chain — theme → plugin → base. Customize anything without forking. Component system for reusable sections.

Security

Membership platforms hold sensitive data — names, emails, payment info, personal details. Security is not a feature here. It is the baseline.

SQL Injection Protection

Every database query uses PDO prepared statements. There are no exceptions and no raw string concatenation paths. This is enforced structurally, not by convention.

XSS Prevention

All user-generated output is escaped with htmlspecialchars. The FormWriter system handles output encoding automatically so individual views cannot forget.

Authentication & Permissions

Session-based authentication with role-based access control. Permission checks happen at the controller level before any data is loaded or rendered.

CSRF Protection

CSRF token generation is built into the FormWriter. Available on every form out of the box — no extra setup required.

Password Hashing

Passwords are hashed with Argon2id — the current best practice. Legacy bcrypt hashes are automatically upgraded on next login. No plaintext, no MD5, no SHA.

Cookie Security

All cookies are set with HttpOnly, SameSite=Lax, and Secure flags. Session cookies are not accessible to JavaScript and are scoped to prevent cross-site request attacks.

Source Available

You can read every line of code that touches your members' data. No obfuscation, no compiled binaries, no trust-us black boxes.

Secure File Handling

File uploads are validated by type and size, stored outside the web root where possible, and served through controlled handlers — not direct URLs.

REST API

Every feature is accessible through the API. Build integrations, automate workflows, or build your own frontend.

  • Key-based authentication
  • 40+ model endpoints
  • CRUD + action operations
  • Rate limiting and CORS
  • JSON request/response
# List members curl -H "X-API-Key: your_key" \ https://yoursite.com/api/users # Get a single member curl -H "X-API-Key: your_key" \ https://yoursite.com/api/users/42 # Create an event curl -X POST \ -H "X-API-Key: your_key" \ -H "Content-Type: application/json" \ -d '{"evt_name": "Monthly Meetup"}' \ https://yoursite.com/api/events

Plugin System

Plugins are self-contained modules that can add data models, views, admin pages, API endpoints, and scheduled tasks. Each plugin has its own MVC structure.

  • Own data models with automatic table management
  • Admin interface pages
  • Custom routes and views
  • Scheduled task support
  • Activate/deactivate without data loss
# Plugin directory structure plugins/bookings/ ├── plugin.json ├─��� data/ │ └── bookings_class.php ├── views/ │ └── booking.php ├── admin/ │ └── admin_bookings.php ├── logic/ │ └── booking_logic.php └── assets/ └── css/style.css

Theme System

Themes control the entire visual presentation. The override chain lets you customize any view, template, or asset without modifying core files.

  • Override chain: theme → plugin → base
  • Multiple included themes
  • Bootstrap, Tailwind, or zero-dependency HTML5
  • Component system for reusable sections
  • FormWriter adapts to your CSS framework
Theme gallery coming soon

Self-hosting

Run Joinery on your own infrastructure. Same software, complete control.

Requirements

PHP 8.x, PostgreSQL, Apache or Nginx. Standard LAMP/LEMP stack — nothing exotic.

Installation

Clone the repo, run the installer, configure your database. Docker supported. Or let us do it with White Glove Install ($249).

Updates

Automated upgrade system. Run one command to pull the latest version and apply migrations.

Explore the source

Joinery is source-available under the PolyForm Noncommercial license. Read the code, file issues, or contribute.