Schema and templates
The schema commands manage a project's structure: features, work item types and their properties, states, labels, workflows, project metadata, and work item and page templates. plane upgrade applies a shared template to an existing project.
Every schema subcommand takes an optional [project] folder name plus --path.
| Subcommand | Label | Flags | What it does |
|---|---|---|---|
schema validate | Safe | --path | Check the local schema files without connecting to Plane. |
schema push | Confirm | -n / --dry-run, -f / --force, --prune | Create the project if needed, then create and update the schema. |
schema import | Confirm | -m / --merge, -f / --force | Map local names to remote IDs; optionally merge or overwrite files. |
schema sync | Destructive | -n / --dry-run, -f / --force | Make the remote schema match local exactly, including deletes. |
schema diff | Safe | --exit-code | Compare local and remote schema. |
schema validate
Checks the files in schema/ offline. Nothing is sent to Plane.
plane schema validateschema push
Creates the project in Plane if it doesn't exist yet (asking first), then creates and updates features, project metadata, work item types and properties, states, labels, workflows and templates. It shows a plan and asks before applying it.
Push is additive. Without --prune, remote work item type properties that aren't in your types.yaml are reported and left alone, so a normal push never deletes property data. With --prune, they're deleted.
plane schema push --dry-run
plane schema push
plane schema push --pruneA successful push ends with Schema push complete! and the created and updated counts. If only some properties failed, it ends with a warning instead. Any hard failure exits 1.
schema import
A Terraform-style import from Plane.
| Mode | Effect |
|---|---|
| (default) | Update .plane/state.json with remote IDs for your local names. Your files aren't changed. |
--merge | Also add types, states, labels and similar that exist in Plane but not locally. Adds only, never overwrites. |
--force | Replace your local schema files with the remote schema. Local edits are lost. |
Run the default mode after a fresh git clone of your config, or after losing .plane/, so the next push updates existing objects instead of trying to create them again.
plane schema import
plane schema import --mergeschema sync
Makes the remote schema match your files exactly. It creates, updates and deletes types, states and labels.
schema sync deletes from Plane
Types, states and labels that exist in Plane but not in your files are deleted. Its --help text says deletes aren't supported yet; in v0.5.2 they are. Plane refuses to delete a state that's in use or is the default, and that's reported as a failure. With workspace-level work item types turned on, type changes and deletes are skipped.
Always run --dry-run first, or use schema push for changes that only add and update.
plane schema sync --dry-run
plane schema syncschema diff
Compares local and remote schema, including workflows, project metadata, features and templates.
plane schema diff --exit-code
echo $?With --exit-code: 0 when in sync, 1 on error, 2 when there are differences.
upgrade
Confirm. Applies a template to an existing project, so many projects can share one standard schema. Items that exist only in your project are kept. Items the template defines are created or updated, and where both define the same item, the template's fields win.
| Flag | What it controls |
|---|---|
-t, --template | Template path, Git URL, or URL@tag. See Template sources. Left out, the template: value in plane.yaml is used. |
-n, --dry-run | Stop before applying the template. Unless you also pass --skip-pull, your local schema has already been refreshed from Plane by then. |
-f, --force | Skip the apply prompt and the "Push changes to Plane now?" prompt, so changes are pushed automatically. Only --schema-only prevents the push. |
--skip-pull | Don't pull the latest schema from Plane first. Combine it with --dry-run for a preview that changes nothing. |
--schema-only | Update the local YAML only. Don't push. |
--include-data | Also copy cycles, modules, work items and pages from the template. If you accept the push, everything is pushed with force and no conflict check. |
What upgrade does, in order:
- Pulls the latest schema from Plane into your files, unless you pass
--skip-pull. - Compares it with the template: types, states, labels, workflows, features, and work item and page templates.
- Shows what will be added, updated and kept, and asks you to confirm.
- Updates your local YAML and saves the template in
plane.yaml. - Offers to push.
plane upgrade -t ./my-template --dry-run --skip-pull # preview, changes nothing
plane upgrade -t https://github.com/org/repo/templates/std@v1.2.0
plane upgrade # reuses the template from the last runThe first upgrade needs -t. plane init records template: default, and the built-in template can't be used for upgrades. After a successful run, template: in plane.yaml is set to the -t value, including any @tag, so later runs can leave -t out.
--dry-run alone isn't read-only
Without --skip-pull, upgrade --dry-run overwrites your local types, states, labels, workflows and features with what's in Plane before it shows the preview. Use --dry-run --skip-pull for a preview that changes nothing.

