Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Tooling

Tooling

The jadpo command

On this page

You work with Jadpo through one command, jadpo, and a short list of subcommands. Run them anywhere inside your project: each finds the project by walking up from the current folder to app.jadpo, so you only give a path to work on another project. Every subcommand takes --json, for output an agent reads instead of prose, except the interactive modes, which need a terminal.

Commands have plain synonyms where people reach for either word, such as fmt and format, and an unknown command suggests the nearest. Tab completes commands, flags and your project's own names, and a command missing an argument asks for it from a searchable list.

The commands you use every day:

Command Does
jadpo new <name> Starts a project
jadpo check Checks everything and writes the derived files in build/
jadpo fmt Formats your code
jadpo test Runs your tests
jadpo build [<deployable>] Builds the programs you deploy, into build/target/
jadpo dev Runs the app locally, rebuilding it on every save

jadpo new

jadpo new <name> starts a project in a folder that doesn't exist yet or is empty, and the project passes jadpo check, jadpo fmt --check and jadpo test as soon as it is written. It writes the fixed root (The root) and one small domain, hello:

text
todo-app/  app.jadpo        application { jadpo: "0.1" } and the project token  config.jadpo     config {}, with no settings yet  policy.jadpo     who may run greet: Access.public  api/    main.jadpo_record    as jadpo api update writes it  domains/    hello/      types/       visitor.jadpo  greeting.jadpo      actions/     greet.jadpo      routes/      hello.jadpo  hello.test.jadpo  database/        empty  tests/           empty  AGENTS.md  .gitignore  .gitattributes
  • app.jadpo names the release line of the jadpo that ran new, so jadpo new from 0.1.x writes jadpo: "0.1" (Which jadpo runs). It also holds the project's suggestions { project_token: }, 32 random hex digits from the operating system's generator (Sharing with Jadpo HQ); when the generator fails it leaves the block out, and share writes it later.
  • The hello domain is one route, POST /hello, with authentication: RouteAuthentication.none. It takes a Visitor and runs greet, which returns a Greeting. Because greet reaches no entity, root policy grants it with hello.greet: [Access.public]. The route's test, beside it, posts a visitor and checks the status and the greeting. The API record is written by the code jadpo api update runs, from these routes.
  • AGENTS.md says what Jadpo is, the release line app.jadpo names, where the docs are (the primer, the index and the error pages on the site, as How an agent uses it describes), and which commands to run after a change. .gitignore holds build/, and .gitattributes holds the lines that keep records readable in a diff (Records and manifest). There are no hidden folders.

The project is named after the folder: the last part of <name>, or the folder it runs in for jadpo new .. A folder that holds anything, hidden files included, is refused with toolchain.scaffold_destination_not_empty and left as it was; a file of that name is toolchain.scaffold_destination_exists, and a <name> that ends in no folder's name, such as .., is toolchain.scaffold_name_invalid. If a write fails partway, jadpo new removes what it wrote and reports toolchain.scaffold_write_failed.

The screen is one status line, then the command to run next:

text
Created todo-app    jadpo  0.1    route  POST /hello    files  12 writtennext: cd todo-app && jadpo dev  serves it on http://localhost:3000

With --json, data holds the path as typed, the root, the jadpo line, the routes and the files it wrote.

jadpo check

jadpo check checks the whole project and writes the files derived from it: build/manifest.json and the catalogues in build/catalogue/ (The build/ folder).

jadpo fmt

jadpo fmt formats every file. It fixes each file's imports first, then lays the file out, writing each file's declarations before their use, the primary declaration last. --check only reports what it would change, and --layout also makes promotion moves (Formatting).

jadpo test

jadpo test runs every test. It runs pure and action tests in the interpreter, route tests, and schedule tests (--kind schedule). It also reads each recording of the app's own integrations through its operation's decoders (--kind recording), and each recorded answer to a prompt through each type the prompt is asked for as. A recording made from an older version of the prompt is an alert on the report and in data.alerts (Kinds of test).

To run fewer tests:

  • jadpo test <file> runs one test file, and <file>:<line> the test at that line. A folder runs the tests under it.
  • --name <text> runs the tests whose names match, --kind route one kind of test, and --failed the last run's failures.
  • --seed <n> reruns the tests in the order a given seed sets.

jadpo test --watch reruns the affected tests on every save. Each save reruns the tests that reach something whose digest, a hash of its code, changed since the last run, within the path, name and kind you gave. While the build is broken it shows the errors and runs nothing. With --json it writes one envelope per line. Ctrl-c quits.

--keep-failed keeps a failed test's database and names it in the report.

jadpo build

jadpo build writes the runnable app into build/target/, with each API's <api>.failures.<locale>.json beside its OpenAPI document (Configuration and time). It takes --json. It first checks as jadpo check does, writing the same files, and stops at the errors.

  • An app that declares no deployables builds its one deployable, app, natively: the binary build/target/app/app, and build/target/app/openapi/ with each API's document and failure files. It is built with the toolchain and lock this Jadpo pins (A native deployable).
  • An app that declares deployables builds every one, or the one you name, each into build/target/<deployable>/ beside only its own APIs' documents (Declared deployables).
  • A deployable built for Target.wasm is a WebAssembly module with Jadpo's module shim and a Wrangler file, and the screen gives the module's size (A Workers deployable).

jadpo dev

jadpo dev runs your app locally and keeps it up to date as you edit. It runs the app in the interpreter at http://localhost:3000 (--port changes it) and prints one line per request with its request id.

Each save that checks cleanly serves the next request. While a save has errors, the last good version keeps serving. --no-run only checks on every save and writes build/, and --json writes one envelope per line.

An editor that saves a file in place first empties it, then writes its text. So a save that leaves a file empty that had text isn't taken as finished yet: the reload waits up to 2 seconds for the file's text. An empty routes file checks cleanly, with no routes, so this keeps a half-saved file from replacing the version serving. A file still empty after that reloads as saved (design notes, "Watching saves"). jadpo test --watch waits the same way.

Settings. The settings config.jadpo declares are read from the environment, then .env.local, and checked before the app starts. A missing or invalid value stops it starting, and the screen names the setting and its variable, never the value. A save of .env.local is checked like a save of source, so the last good version keeps serving.

Databases. Each database opens at the address its connection's url: setting holds, or the one --url names. A store whose address no variable gives gets a disposable PostgreSQL for the session. Jadpo starts that from PostgreSQL's own programs (initdb, pg_ctl and postgres), so PostgreSQL has to be installed on your machine; you don't create a database or set a password. Pending migrations are applied as they appear. While it runs, the address of each database it started is in build/dev/stores.json, for jadpo schedules and jadpo why.

Background work. Each schedule run and each skipped tick (a paused schedule's, once) gets a line with its trace's id, its outcome, what it emitted or its failure, and its time. Each alert gets a line when it starts. Each step reached by an action with several changing calls is a line under its request's line. A delivery whose action reached steps gets a line of its own, with jadpo deliveries show <id> when it needs an operator (Jobs and events).

Provider calls. Every call to an outside provider is faked by default, so you need no credential. A connection's development: { sandbox: } lets calls through to the provider's sandbox, never to its live service. --fake <connection> and --sandbox <operation> change which for one session only. Each request's line lists its calls, and each call is logged for jadpo calls (Provider calls in development).

Stopping. Ctrl-c or SIGTERM stops it cleanly: the server finishes the requests it has, its background work gives back what it holds, and it exits 0. A second signal ends it at once (Running background work).

Not built yet:

  • jadpo test --affected, which runs the tests a change reaches, measured against the merge-base with main.
  • jadpo test --interactive, a keyboard view of every test: search, move between tests, run a file, one test or all, rerun failures and turn watching on and off (Testing). The flag says toolchain.not_built_yet.
  • The trace --keep-failed keeps, which comes with Debugging and review.
  • jadpo dev starting the services the app's connections declare (External services).

Markdown for agents: /docs/the-jadpo-command.md.Built from Jadpo main at a707efb.