Community software for people who want to build something together. meith.dev
The internet used to feel like a neighborhood, but today, it often feels like a fragmented crowd. We wanted to build a platform that brought the neighborhood back.
We named our software Meith after the ancient Irish concept of meitheal: a group of people coming together to help one another with a shared task. In a true meitheal, expertise is shared freely, heavy lifting is distributed, and the community grows stronger through cooperation. Meith provides the digital infrastructure for modern communities to do exactly that. Whether your users are trying to fill a regional networking gap, build open-source software, or share a niche hobby, Meith gives them the space to gather and grow.
On your own server, with nothing between you and the board. The Quickstart goes from a fresh Ubuntu box to a board on your own domain, over HTTPS, in about twenty minutes.
Coolify is the short way, and it is still entirely your own server — a panel you install on the same machine, not a service you sign up to:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bashThen point it at this repository — the release branch — and
docker/compose.coolify.yml. It pulls the
released image rather than building anything, generates both secrets and the
database password, issues the certificate, tells the board its own URL, and
follows releases — never bare pushes — on redeploy. Nothing is typed in.
Or the compose file directly, if you already run a proxy:
git clone https://github.com/meith-dev/meith.git && cd meith/docker
git checkout "$(git describe --tags --abbrev=0)" # the newest release
cp ../.env.example .env # three secrets, generated not typed — the file says how
docker compose up -d --buildThe same four containers either way — Postgres, a one-shot migration that the
other two wait on, the web server, and the worker that runs the background
tick. Coolify pulls them as the released image;
docker/compose.yml builds the same image from the
checkout. Certificate in front, open /install, and that is a board.
That route is the advanced one — Deploying by hand
covers the .env, the proxy and what you take on for it. Day two, either way,
is Running a board.
Those are the only deployment routes this project supports, and that is a decision rather than an omission. A board asks three things of wherever it runs — a scheduler that goes off every minute, a disk that survives a restart, and a process that outlives a request. A plain server gives you all three without being asked; a serverless host gives you none, and the third has no workaround at any price.
- A real permission model. 46 permission fields — 27 resolved per actor per forum, 19 board-wide — not a three-tier guess. Search, feeds and the API all answer to it, so there is no path that reads around the rules.
- Themes that cannot break the board. A frozen slot contract, documented and generated from the registry, so a theme is replaceable rather than a fork.
- Plugins with contained failures. Hooks with typed payloads; a plugin that throws does not take a page down with it.
- Postgres full-text search, weighted so a thread's subject beats a passing mention, and paged on a keyset so results never repeat or skip.
- Spam controls that fail open. A honeypot, a fill-time floor, questions you write yourself, held first posts, and hourly limits counted in the database so every instance shares one allowance. No hosted captcha, so no third party meets your members before you do.
- A migration path from MyBB — resumable, so a large board can be imported across several sessions.
- An operator CLI for everything you should not need a browser for: migrations, users, settings, scheduled tasks, search reindexing.
Every document lives in docs/ and nowhere else. The site at
meith.dev/docs renders those same files — it holds no
copy of any of them — so a correction is one edit, in the repository, and both
places have it.
The table below is written from apps/web/content/docs.manifest.json by
pnpm site:docs. Describe a document there; do not edit these rows.
| Section | Document | What it answers |
|---|---|---|
| Running a board | quickstart.md |
From nothing to a board people can reach, on your own server with Coolify. About twenty minutes, and the deploy pulls the released image rather than building anything. |
| Running a board | operating.md |
The operator handbook. Configuration, permissions, themes, plugins, spam, migrations, backup and restore, connection pooling, and the failures that actually happen. |
| Running a board | upgrading.md |
How to take a board from one version to the next, how far you can jump, and what to do when a migration fails halfway. |
| Running a board | performance.md |
The p95 budgets for the hot pages, and what the last recorded run measured against a full-scale board. (generated) |
| Running a board | demo-mode.md |
A public board with its password printed on it, seeded with content, that deletes everything and rebuilds itself on a timer. What runs at demo.meith.dev. |
| Advanced deployment | self-hosting.md |
The same board without a panel: Docker Compose, a .env you write, and a reverse proxy you run. Advanced — the Quickstart is the route most boards should take. |
| Themes | theme-api.md |
What the freeze covers, what a theme may do, and how to write one. |
| Themes | theme-slots.md |
Every slot and every view model, generated from the theme registry. (generated) |
| Plugins | plugin-api.md |
What a plugin is, what it may and may not do, and how a failure is contained. |
| Plugins | plugin-hooks.md |
Every hook and payload, generated from the hook registry. (generated) |
| The API | rest-api.md |
Every endpoint, scope and rate limit, generated from the route registry. (generated) |
| Migrating from MyBB | mybb-parity.md |
Every place this board behaves differently from MyBB, with the reason. Read it before promising anyone a like-for-like move. |
| Development | development.md |
Running the board on your own machine, the workspace layout, the commands, and what to do before opening a pull request. |
| Development | architecture.md |
How it fits together: the processes, the layers, the path a request takes, and the seams everything else hangs off. |
| Development | nextjs-conventions.md |
Server components, caching, forms and errors — the decisions that would otherwise be re-litigated in every pull request. |
| Development | release.md |
How a version is cut: the lockstep version rule, what each release publishes — the image, the branch, the npm packages — and the migration policy behind the numbers. |
docs/README.md is the same set, read from the repository
rather than the site.
A pnpm workspace. Node 22+, pnpm 10, and nothing else to start:
pnpm install
pnpm devThat is a working board on http://localhost:3000 with no database — a deterministic in-memory sample board, enough to read every page and try a theme. Posting needs Postgres, which is one more command. Development is the full walkthrough: the dev database, the commands, the gates, and what to do before opening a pull request.
pnpm verify runs what CI's static job runs — the invariant guards, the
generated-doc checks, lint, dependency rules, all three typecheck projects and
the full test suite. CI's other jobs build the image and drive a browser; the
static job is the one a pull request fails first.
Four applications share the workspace:
| Directory | Package | What it is |
|---|---|---|
apps/community |
@meith/web |
The board itself. pnpm dev. |
apps/web |
@meith/site |
meith.dev — the landing page and the documentation. pnpm site:dev, on port 3100. |
apps/worker, apps/cli |
@meith/worker, @meith/cli |
Background work, and the operator CLI. |
apps/web renders docs/*.md at build time. It does not copy them, and there is
no second place to update when a document changes.
Meith is free software under the GNU Lesser General Public License, version 3
or later — LICENSE.md.
LGPLv3 is not a standalone licence: it is a set of additional permissions layered
on top of the GNU GPL, which it incorporates by reference. That text is
COPYING, and the two files together are the terms.
What it means in practice — a summary with no legal effect of its own, and not legal advice:
- Run a board on it, for anything, including commercially. Nothing asks you to publish your configuration, your members' data, or a word anybody wrote on your board. Running the software is not distributing it.
- Write a theme or a plugin, and licence that however you like. A theme fills the frozen slot contract; a plugin listens on typed hooks. Both use an interface Meith provides rather than becoming part of Meith, which is the case the Lesser GPL exists to allow. Yours is not obliged to be LGPL because the board it runs in is.
- Change Meith itself, and those changes carry the same licence to whoever you hand the modified version to, along with the source and a note of what you changed. That is the copyleft, and it is the whole of what is asked in return.
- There is no warranty. Sections 15 and 16 of
COPYINGsay so at length.
The FSF also recommends a notice at the top of each source file. Meith does not
carry them yet; the licence applies to the whole work either way. The boilerplate
is at the end of COPYING — insert "Lesser" before "General" in all three places
to refer to the LGPL rather than the GPL.
Copyright (C) 2026 the Meith contributors.