palinxdocs

CLI reference

The px CLI drives a project from scaffold to production. Install it once with bun add -g @palinx/cli and the px command is on your PATH. A scaffolded app also wires the common commands into its package.json scripts, so you'll often run them through bun run, but each is available directly.

Run px --help at any time for the full list.

scaffold

Scaffold a new project.

px scaffold webapp my-app

scaffold writes the project from a template, installs dependencies, and leaves you ready to run. See Scaffolding for the available templates and how to choose between them.

Run it bare and it goes interactive: a menu picks the template and prompts for the project name.

px scaffold

Pass --into-existing to scaffold alongside files that are already there; it writes per-file and skips anything that already exists, so it won't clobber your README.md, .git/, or other files you manage:

px scaffold webapp . --into-existing

dev

Start the development server.

px dev

dev serves your app, watches src/, and reloads on change. The port resolves in this order: --port= flag, then the PORT environment variable, then server.port from palinx.config.ts, then the default 2500. An invalid value in one tier falls through to the next. If your project has a src/scheduled/ directory, dev also boots the scheduler.

px dev --port=3000       # override the configured port
px dev --no-scheduler    # skip booting src/scheduled/ tasks
px dev --inspect         # boot under Bun's inspector
  • --port=NNNN overrides the port for this run. Note the equals form: --port=3000. A space-separated value (--port 3000) is ignored and the next tier wins.
  • Because PORT sits above the config in that order, a PORT exported globally in your shell is picked up by dev and beats server.port. If the dev server binds a port you didn't expect, check your environment.
  • --no-scheduler starts the server without booting the tasks in src/scheduled/, which is useful when you're iterating on the app and don't want jobs firing alongside it.
  • --inspect boots the dev server under Bun's inspector for server-side debugging; it prints a debug.bun.sh link to attach to. Pass --inspect=host:port to pin where the inspector listens. See Debugging for the full workflow.

make

Generate a component, service, route, or API endpoint with the right boilerplate.

px make component user-badge
px make service billing
px make route dashboard
px make api billing-reports

Each writes a correctly-shaped file into the matching src/ directory so you start from a working stub instead of an empty file:

Command Writes
px make component user-badge src/components/user-badge.ts
px make service billing src/services/billing.service.ts
px make route dashboard src/routes/dashboard.route.ts
px make api billing-reports src/api/billing-reports.ts

Those four kinds (component, service, route, api) are the full set. The generated api class mounts at /api/<name> and answers with an empty JSON list until you fill it in.

test

Run your test suite through Bun's test runner.

px test

Exits non-zero on failure, so it fits straight into CI. Every argument is forwarded verbatim to bun test, so anything Bun's runner accepts works here:

px test --watch              # re-run on change
px test tests/auth.test.ts   # a single file
px test -t "logs in"         # only tests matching a name filter

See Testing for writing tests.

build

Produce the production build.

px build

build compiles your app into a self-contained build under dist/ (configurable via build.outDir). See Deployment for what it produces and how to run it.

serve

Run your app in production mode from the project directory.

px serve

serve runs a production server from your project, layering in production concerns and running scheduled tasks, using the built assets from build. It's one of two ways to run in production; build also emits a self-contained standalone bundle you can run on its own. Deployment covers both modes and when to use each.

px serve --port=8080       # override the port
PORT=8080 px serve         # or via the environment
px serve --no-scheduler    # skip booting src/scheduled/ tasks

The port resolves exactly as in dev: --port= flag, then the PORT environment variable, then server.port from palinx.config.ts, then the default 2500, with invalid values falling through to the next tier. The flag uses the equals form; --port 8080 with a space is ignored. --no-scheduler runs the server without booting scheduled tasks, which fits setups where a separate instance owns the jobs.

--version

Report what you are actually running.

px --version

Run this before filing a bug report. Your package.json records the version ranges you asked for, which is a different thing from the versions that ended up installed; a range of latest tells nobody anything. --version reads the packages resolved under node_modules, so it reports what your app is really executing.

Outside a project it prints just the CLI's own version:

px 0.2.0

Inside a project it also lists the resolved @palinx/* packages and the Bun version:

px 0.2.0

  Project packages (resolved from node_modules):
    @palinx/cli        0.2.0
    @palinx/compiler   0.2.0
    @palinx/core       0.2.0
    @palinx/router     0.2.0
    @palinx/scheduler  0.2.0

  Bun 1.3.14

-v is an alias for the same thing.

A package your project declares but has not installed is listed too, marked so you can see the gap rather than having it silently omitted. If you see that, run bun install.

update

Move a project onto the newest @palinx/* packages its version ranges allow.

px update

This updates every @palinx/* dependency in the current project, lockfile included. It is the command to reach for when a release has shipped and you want it; a scaffolded project usually permits the new version already, and what pins you to the old one is the lockfile rather than the range.

To update the globally installed CLI instead:

px update --self

The default is deliberately the project, not the CLI. A global install is shared by every project on your machine, so a command that quietly changed it would be a surprise. Run px update outside a project and it stops with an error pointing you at --self.

Both forms report what moved, and say so plainly when nothing did:

  Updated:

    @palinx/core  0.1.1 -> 0.2.0   (range latest -> ^0.2.0)
    @palinx/router  0.1.1 -> 0.2.0   (range latest -> ^0.2.0)

Open ranges gain a ceiling

Notice the (range latest -> ^0.2.0) above. Updating rewrites the range in your package.json as well as the lockfile, and when the old range was open, latest or >=0.1.0 or *, the replacement carries an upper bound that you never wrote. The command calls this out when it happens:

  Note: bun update narrowed an open version range for @palinx/core, @palinx/router.
  Those now carry an upper bound they did not have before, so future
  updates will stop at it. Edit package.json if you meant to stay open.

Nothing is broken, but your manifest is now stricter than it was, and the next release outside that bound will not arrive on its own. Edit package.json if you would rather stay open. The command does not rewrite the range back for you, because fighting your package manager over your own manifest is worse than telling you what it did.

Ranges that already had a ceiling, anything starting with ^ or ~, are not affected and are not reported this way.

Updates stop at the next minor

A caret range on a 0.x version accepts patch releases only, so ^0.2.0 takes 0.2.1 and 0.2.7 but stops before 0.3.0. Below 1.0 a caret treats every minor bump as a breaking change, which means each new minor sits outside the range your project already carries. Once your project carries ^0.2.0, px update will keep reporting this even after 0.3.0 is published:

  Already up to date. Nothing changed.

    @palinx/core  0.2.0

That is semver behaving correctly rather than a failure. The new minor sits on the other side of the ceiling your range declares, and the update command will not cross it for you. To take it, either widen the range in package.json and run px update again:

"@palinx/core": "^0.3.0"

or install the version directly:

bun add @palinx/core@latest

Pre-1.0, minor releases are where the meaningful changes land, so it is worth checking for a new one rather than trusting "already up to date" to mean "on the newest release".

Next

Deployment puts build and serve together into a production workflow.