<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mlzog</title>
    <description>The latest articles on DEV Community by mlzog (@mlzog).</description>
    <link>https://dev.to/mlzog</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4106295%2F37f6f44f-6be7-468c-9336-dea196050744.png</url>
      <title>DEV Community: mlzog</title>
      <link>https://dev.to/mlzog</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mlzog"/>
    <language>en</language>
    <item>
      <title>I built a zero-dependency forum in pure PHP</title>
      <dc:creator>mlzog</dc:creator>
      <pubDate>Wed, 02 Sep 2026 13:55:26 +0000</pubDate>
      <link>https://dev.to/mlzog/i-built-a-zero-dependency-forum-in-pure-php-4ba6</link>
      <guid>https://dev.to/mlzog/i-built-a-zero-dependency-forum-in-pure-php-4ba6</guid>
      <description>&lt;p&gt;A few months ago I got tired of how complicated modern forum software has become.&lt;/p&gt;

&lt;p&gt;Want a simple place for people to discuss something?&lt;br&gt;&lt;br&gt;
Most options expect Docker, Redis, a proper VPS, Composer, and a non-trivial amount of setup.&lt;/p&gt;

&lt;p&gt;I believe &lt;strong&gt;everyone should be able to install a forum easily&lt;/strong&gt;, even on very cheap or free shared hosting. No root access, no containers, no complex stack.&lt;/p&gt;

&lt;p&gt;Classic forum software is often still the easiest to install, but the default look and feel usually shows its age. Modern alternatives look better, yet they tend to come with heavier requirements. I wanted something in between: easy to deploy, simple at the core, and reasonably modern (and easy to theme).&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;bulletinbored&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvav7rfdv2d8l0atnr2fs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvav7rfdv2d8l0atnr2fs.png" alt="bulletinbored admin dashboard" width="799" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;bulletinbored is a minimal, extensible forum written in plain PHP.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero external dependencies&lt;/strong&gt; — no Composer, no npm, no Docker&lt;/li&gt;
&lt;li&gt;Works with &lt;strong&gt;PHP 8.1+&lt;/strong&gt; and PDO (SQLite or MySQL)&lt;/li&gt;
&lt;li&gt;Upload the files → run the 3-step installer → done&lt;/li&gt;
&lt;li&gt;Clean URLs, moderation, roles &amp;amp; permissions, plugins, themes, localization&lt;/li&gt;
&lt;li&gt;Built-in update system for core, plugins and themes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see the forum in action here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.bulletinbored.net/forum/" rel="noopener noreferrer"&gt;https://www.bulletinbored.net/forum/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The core stays small on purpose. Extra features (rich editor, private messages, notifications, etc.) live in optional plugins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why zero dependencies?
&lt;/h2&gt;

&lt;p&gt;The main reason is accessibility.&lt;/p&gt;

&lt;p&gt;A lot of people still use cheap or free shared hosting. On those environments Composer is often unavailable or painful, Docker is impossible, and you rarely have root. I wanted the software to work in that reality.&lt;/p&gt;

&lt;p&gt;There are secondary benefits too: the entire codebase is easy to audit, there is no dependency tree to monitor for supply-chain issues, and fewer moving parts that can break when the hosting environment changes. Of course this comes with trade-offs — you reimplement things that mature libraries already solve well. For a focused project of this size, it felt like the right compromise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical choices
&lt;/h2&gt;

&lt;p&gt;Some decisions that shaped the project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Simple front controller + focused &lt;code&gt;src/&lt;/code&gt; core. No full framework. Managers for plugins, themes and updates live in &lt;code&gt;lib/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Centralized &lt;code&gt;AuthZ&lt;/code&gt; service with permission checks (&lt;code&gt;threads.create&lt;/code&gt;, &lt;code&gt;posts.edit_own&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSRF tokens that rotate after every successful validation
&lt;/li&gt;
&lt;li&gt;Content Security Policy with nonces
&lt;/li&gt;
&lt;li&gt;Real MIME detection + structural checks for uploads
&lt;/li&gt;
&lt;li&gt;Server-side enforcement of bans/suspensions on every request
&lt;/li&gt;
&lt;li&gt;Zip Slip protection when installing plugins/themes
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Database&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
File-based migrations. SQLite works well for small communities; MySQL is supported too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Plugins can register hooks and routes. Themes are basically a folder with CSS (and optional templates).&lt;/p&gt;

&lt;h2&gt;
  
  
  About the license
&lt;/h2&gt;

&lt;p&gt;The project uses the &lt;strong&gt;BSD Zero Clause License (0BSD)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I deliberately chose the most permissive license available. Part of the code was written with AI assistance, and there is no established community around the project yet. I wanted to maximize the chances that the code remains usable and can be adopted, forked, or continued by others, even if I eventually stop maintaining it.&lt;/p&gt;

&lt;p&gt;0BSD places almost no restrictions on use, modification, or redistribution. If a real community forms around the project in the future, any decision about changing the license can be made together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current status
&lt;/h2&gt;

&lt;p&gt;The project is at &lt;strong&gt;0.8.x&lt;/strong&gt; and moving toward 1.0.&lt;/p&gt;

&lt;p&gt;The architecture has been cleaned up a lot recently (modular helpers, proper Response objects, middleware router, better tests). There are still bugs and rough edges — this is not production-perfect yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Forum in action: &lt;a href="https://www.bulletinbored.net/forum/" rel="noopener noreferrer"&gt;https://www.bulletinbored.net/forum/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;a href="https://www.bulletinbored.net" rel="noopener noreferrer"&gt;https://www.bulletinbored.net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/bulletinbored/bulletinbored-core" rel="noopener noreferrer"&gt;https://github.com/bulletinbored/bulletinbored-core&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Available themes and extensions: &lt;a href="https://extend.bulletinbored.net/" rel="noopener noreferrer"&gt;https://extend.bulletinbored.net/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://docs.bulletinbored.net" rel="noopener noreferrer"&gt;https://docs.bulletinbored.net&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I'd love feedback on
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Does the “upload and run on cheap/free hosting” goal still make sense?&lt;/li&gt;
&lt;li&gt;Is the security model (trusted admin + HTTPS + integrity checks) reasonable for this kind of software?&lt;/li&gt;
&lt;li&gt;What do you consider must-have before calling a forum “1.0”?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading.&lt;br&gt;&lt;br&gt;
If you try it, I’d be happy to hear what breaks.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>php</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
