Yeollin CMS is a Tauri-inspired, plugin-based CMS framework rather than a finished CMS product. A plugin is a single Rust crate that bundles its Axum/Vespera API routes, a vinext (Vite + RSC, Next-compatible) frontend under app/, and optionally sea-orm models with vespertide JSON migrations. The yeollin-cli binary assembles the registered plugins into one application: it extracts the frontend template, merges each plugin's pages, statically exports the result, and embeds it into the release binary via include_dir!, so a deployment is a single executable that serves both the API and the UI.
Status: v0.1, pre-release. APIs change without notice. Not production ready.
This repository is private and under active development. Treat every public interface, file layout, and CLI flag as unstable.
| Tool | Notes |
|---|---|
| Rust (stable) | The workspace targets edition = "2021". cargo clippy is used in CI, so install the clippy component. |
| Bun | Node workspace manager and script runner (bun install, bun run lint). |
| Node | Required by oxlint, which loads oxlint.config.ts through Node rather than Bun. |
| Path | Contents |
|---|---|
crates/ |
The Rust workspace crates: core (shared types), auth (JWT, Argon2, middleware), plugin (PluginMetadata, FrontendAssets), plugin-macros (yeollin_plugin!, yeollin_app!), app (YeollinAppBuilder runtime), cli (init, prebuild, dev, build). |
packages/ |
The Node workspace. packages/app is the vinext frontend template that gets extracted into .yeollin/app/ at prebuild time. It is a template, not the running app. |
plugins/ |
Plugin crates. auth owns accounts and sessions; audit-log reads explicitly marked outbox events; forms owns validated public forms and a private submission inbox; redirects owns exact permanent legacy URL redirects; media owns runtime image uploads; content demonstrates compile-time typed draft/publish collections; search indexes content with SQLite FTS5; webhooks delivers signed events with retry and dead-letter history; example-plugin is a minimal library plugin; example-memo-plugin demonstrates database CRUD, typed settings, and audited events. |
apps/ |
Standalone application crates. apps/example-app wires the example plugins together with yeollin_app! and is the entry point used for local development. |
.yeollin/ is generated during prebuild and is gitignored. Never edit it by hand.
bun install
cd apps/example-app
cargo run -p yeollin-cli -- devdev serves everything on a single port (3001). The Axum router handles the API
routes and proxies everything else to an internal vinext dev server on port
3000, including the Vite HMR WebSocket at /__vite_hmr.
| Variable | Purpose |
|---|---|
PORT |
API server port. apps/example-app defaults to 3001. |
JWT_SECRET |
Signing secret for auth tokens. The server refuses to start unless it is at least 32 bytes. |
YEOLLIN_ADMIN_USERNAME / YEOLLIN_ADMIN_PASSWORD |
Read once by the auth plugin to create the first administrator while the users table is empty. The password must be at least 12 characters, is stored as an Argon2 hash, and is never compared in plaintext. |
YEOLLIN_DEV_PROXY |
Enables the dev proxy to the vinext port. |
YEOLLIN_STORAGE_DIR |
Writable runtime-object root. apps/example-app defaults to ./storage; mount and back it up when using media. |
YEOLLIN_EXPORT |
Makes the binary print one metadata JSON document on stdout and exit, which is how prebuild discovers its plugins, menus, and routes. |
cd apps/example-app
cargo run -p yeollin-cli -- buildThe build runs in four stages:
cargo buildproduces a binary that can export plugin and menu metadata.yeollin prebuildextracts thepackages/apptemplate into.yeollin/app/, copies each plugin'sapp/pages in, and writesmenus.jsonandplugins.json.vinext buildstatically exports to.yeollin/app/dist/client/, and the CLI copies the client output to.yeollin/app/out/.cargo build --releaseproduces the final binary, embedding the static files viainclude_dir!.
Pass --skip-backend to stop after the frontend export, which is what CI does on
pull requests.
These are exactly the commands CI runs, in order. Run them from the repository root unless noted.
bun install --frozen-lockfile
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
bun run lint
for pkg in packages/app apps/example-app plugins/*/; do
[ -f "$pkg/tsconfig.json" ] || continue
(cd "$pkg" && bun x tsc --noEmit)
done# from apps/example-app
cargo run -p yeollin-cli -- build --skip-backendCI additionally builds the release binary with
cargo build --release -p example-app, but only on main.
- Architecture overview
- Plugin authoring
- Forms plugin
- Redirects plugin
- Contributing guide
- Security policy
- Changelog
MIT. See LICENSE.