| name | halo-plugin-dev |
| description | Use when creating or modifying a Halo CMS plugin: writing Java backend code, configuring plugin.yaml, defining custom extensions (GVK), creating custom APIs (CustomEndpoint, MVC controllers), building Vue-based UI with @halo-dev/ui-shared, setting up Gradle builds with DevTools, defining RBAC role templates, declaring pluginDependencies, exposing or consuming plugin extension points, publishing shared events, registering custom FormKit inputs, generating API clients from OpenAPI, registering theme-side Finder APIs, or handling plugin lifecycle (start/stop/delete).
|
Halo Plugin Development
Halo is built on Spring Boot + Spring WebFlux + Vue 3. A plugin consists of:
- Backend (Java): runs inside Halo's JVM, uses Spring DI, reactive WebFlux, custom extensions (CRD-like), and custom APIs
- Frontend (Vue/TypeScript): built into
main.js + style.css, injected into Console and UC (User Center)
- Manifest (
plugin.yaml): plugin metadata, dependencies, settings, and config map names
Important: Halo's plugin APIs, VO field names, extension annotations, and UI APIs evolve across versions. Do not rely on training data for specific field names, method signatures, or type structures. When writing code that accesses extension fields or calls shared beans, always fetch the relevant online doc from the References section below first.
Quick Start
Create a new plugin project using the official scaffolding tool:
pnpm create halo-plugin
Follow the prompts (plugin name, domain, author, UI build tool: Rsbuild or Vite).
Then run with DevTools (requires Docker):
./gradlew haloServer
Visit http://localhost:8090/console — username/password defaults to admin/admin.
After code changes:
./gradlew reload
Or use watch for auto-reload:
./gradlew watch
Development Workflow
- Scaffold:
pnpm create halo-plugin
- Backend: write Java code under
src/main/java/
- Frontend: write Vue/TS code under
ui/src/ (or console/src/)
- Manifest: configure
src/main/resources/plugin.yaml
- Extensions: declare YAML resources under
src/main/resources/extensions/
- Run:
./gradlew haloServer (with Docker)
- Test: visit Console at
http://localhost:8090/console
- Build:
./gradlew build produces a JAR for distribution
References Index
| File | Content | When to read |
|---|
| references/api-changelog.md | High-impact plugin API changes by Halo version, with docs routes | Before using version-sensitive APIs, upgrading Halo dependencies, or raising spec.requires |
| references/plugin-structure.md | Directory structure, backend/frontend layout, build.gradle basics | Creating a new plugin from scratch or understanding the directory layout |
| references/plugin-manifest.md | plugin.yaml fields, version requirements, dependencies, settings/configMap | Writing or editing plugin.yaml |
| references/plugin-interaction.md | pluginDependencies, API modules, shared events, defining and consuming plugin extension points | Depending on another plugin, exposing an API module, sharing events, or making a plugin extensible |
| references/devtools.md | haloServer, reload, watch, generateApiClient, generateRoleTasks, debug config | Running ./gradlew haloServer, hot reload, or debugging a plugin |
| references/server-extension.md | Custom Extension (GVK), AbstractExtension, CRUD APIs, indexes, field/label selectors | Defining a custom data model, storage, or query indexes |
| references/server-api.md | CustomEndpoint, @Controller with @ApiVersion, query params, validation, OpenAPI docs | Writing a new backend API endpoint or controller |
| references/server-lifecycle.md | BasePlugin lifecycle (start/stop/delete), Scheme registration/cleanup |