Skip to content

Development

Commands you'll run dozens of times a day while building.

orion dev

Run your app locally and let the host EMR iframe it for live preview. The CLI starts a Vite dev server, opens a Cloudflare tunnel, and registers the tunnel with your sandbox tenant.

bash
orion dev

The CLI prints the local Vite URL, the resolved tunnel URL, and registers the tunnel with your sandbox tenant. Save a file in your editor to trigger HMR inside the iframe.

Flags

FlagDefaultPurpose
-p, --port <port>5173Dev server port.
--no-tunnelSkip the tunnel. Only useful if you've configured the sandbox to reach localhost directly (rare).

The CLI bundles cloudflared via the npm cloudflared dev dependency and invokes that binary directly. There's a --tunnel-provider flag that's parsed for forward compatibility, but cloudflared is the only provider currently wired through.

Requires

orion config sandbox must be set. orion dev won't fall back to the home tenant — this is intentional, so dev code never runs against your home tenant. See Host vs Sandbox.


orion build

Run your production build into dist/.

bash
orion build

Flags

FlagDefaultPurpose
-o, --out-dir <dir>distOutput directory. Override only if your vite.config.ts already does.
--no-minifyDisable minification (useful when chasing a stack trace through the bundle).
--sourcemapEmit source maps.

orion validate

Run all the checks orion publish runs, but stop before authentication and upload — manifest schema, bundle layout, scope rules, archive forbidden-paths. Catches issues early so you fix them before authentication and upload.

bash
orion validate

The CLI prints one section per check group (Manifest (orion-app.json), Bundle (dist/index.js), Source archive) followed by a summary line — 0 problems found., 0 problems, 1 warning., or 2 problems, 0 warnings.

publish runs validate too — running it explicitly during development gives you faster feedback.

Schema checks include the extensions.writableExtensions block when present: required fields (key, title, valueType, appliesTo), kebab-case key shape, the 9-value-type allow-list, duplicate keys across entries, and the 50-entry manifest cap. Mismatches surface with the offending index and field name — fix in orion-app.json and rerun.

Flags

FlagPurpose
--manifestValidate the manifest only; skip bundle + source-archive checks. Useful for checking a manifest before npm run build.
--jsonEmit findings as newline-delimited JSON, one record per line. CI-friendly.

orion doctor

Environment + manifest health check. Validates Node/npm versions, working-directory config, manifest shape, build artifacts, and (optionally) network reachability of the host tenant.

bash
orion doctor

Sections checked: Environment, Authentication (local), Working directory, Manifest, Build, and (with --network) Identity. Each check is (pass), ! (warn), or (fail). A exits non-zero.

Flags

FlagPurpose
--jsonMachine-readable JSON output for CI scripting.
--networkOpt-in remote-identity verification. Otherwise the doctor stays local-only.

orion generate <kind> <id>

Aliased as orion g. Scaffold a new extension into the current app — manifest entry plus the corresponding source file. The available mount points, triggers, and placements match what the host EMR currently supports.

bash
orion generate page reports --path /reports
orion generate block status-bar --target encounter-detail/status-bar --action after
orion generate widget patient-vitals --mount-point patient-detail-sidebar
orion generate action send-summary --trigger patient-context-menu
orion generate nav reports --placement sidebar --path /reports --icon FileText

Kinds

KindRequired flagsOptional flags
page <id>--path <path> (default /<id>), --layout app|fullscreen|modal (default app)
block <id>--target <name>--action before|after (default before)
widget <id>--mount-point <slot>
action <id>--trigger <name>
nav <id>--placement <name>, --path <path>--icon <lucide-icon> (default LayoutDashboard)

All subcommands accept --force to skip catalog/collision/overwrite checks.

For the field shape of each manifest entry generate writes (and how to hand-edit one), see Manifest schema.

What it writes

For each invocation, generate writes two things:

  • An entry under the matching extensions.pages[] / extensions.blocks[] / extensions.widgets[] / extensions.actions[] / extensions.navigation[] array in orion-app.json.
  • A starter source file in the matching plural directory (src/pages/, src/blocks/, src/widgets/, src/actions/, or src/nav/) named <PascalCaseId>.tsx (.ts for actions). The generator also adds an import for the new component to your entry file (src/main.tsx or equivalent) — wire the route or mount manually.

Documents @orion-ehr/cli v0.0.15 — released under the MIT License.