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: Project layout and modules

Project layout and modules

Imports

On this page

With imports, the place every name comes from can be read from the file itself. Without them, a name in one file could be declared in that file, in its domain's types/, failures/ or entities/, in shared/, or in another domain, and you or an agent would have to search for it.

Each use line names a folder, then the names it brings in, written exactly as the code uses them, so finding a name on the page finds its import. In domains/sales/actions/price_basket.jadpo:

example
use shared/types { Percent, Sterling }use shared/libraries { pricing }use sales/types { Basket, DiscountCode, Receipt }use sales/failures { BasketEmpty, CodeUnknown, DiscountTooLarge }use sales/actions { price_lines }use menu

The braces hold a list separated by commas, the only one in the language: every other block holds one name: value item per line.

What is imported

  • Every name not declared in the file is imported, your own domain's included. A name brought in from sales/types is in domains/sales/types/<name>.jadpo, and one from shared/types is in shared/types/<name>.jadpo. The path leaves out domains/, so shared, app, config, authentication, policy and flags can't name a domain.
  • What the project declares is imported, root files included. A connection in app.jadpo comes in as use app { ... }.
  • Built-ins are never imported. Built-in types (Text, Int, List<T>) and standard-library namespaces (list.count(...)) are fixed per language version, and a project can't declare them. An entity's generated operations (Todo.get(id)) come with the entity.
  • The generated namespaces (clock, config) are called through their names, as the standard library is, and need no import.
  • Calls into another domain keep the domain's name at the call. use menu brings in the domain, and its public actions, queries and fixtures are called as menu.stock_item(...), so a call that crosses domains shows on its own line. Another domain's public types and failures come in by folder like any other name: use menu/types { MenuItem }.
  • A test file sees everything its subject file declares without importing it, so stock_item.test.jadpo calls the loaf_stock helper in stock_item.jadpo directly. Anything else it uses is imported.
  • An entity's provided not-found failure (Reads and writes) comes in from the entity's folder: use planning/entities { Todo, TodoNotFound }.

So a name you read has one of three answers: it is on a use line, so it is in <folder>/<name>.jadpo; it is a built-in; or it is declared in this file.

The standard library's namespaces are list, set, map, range, integer, decimal, money, units, text, markup, hash, encoding, crypto, random, json, csv, tsv, json_lines, temporal, locale, colour, media, web, semver, geo and ai (Standard library). Each is reserved by semantic.standard_namespace_reserved, so nothing in a project can take its name. Fields and named arguments keep every word: note.text and set: are fine.

The formatter keeps imports

jadpo fmt, or the editor, adds a missing import and removes an unused one, one line per folder, sorted. Every name a file can import is unique where it can be imported: a private function or type within its own domain, anything importable across domains across the project. So the import for a name is never in doubt, and a forgotten one is fixed for you rather than being a compile failure. jadpo check still reports an import that names nothing, and one the file doesn't use.

Go to definition works from any use of a name, in a body, a signature or a use line, and opens its declaration in its .jadpo file.

Where the lines go

use lines open the file, below the comments that open it, up to a blank line. use is a reserved word, so nothing is named use.

jadpo fmt sorts them as the example above is:

  • names before domains;
  • from the root files, through shared/, to each domain's folders by domain name;
  • a domain's or shared/'s folders in the order the layout lists them (entities/, types/, failures/ and so on);
  • then the use <domain> lines.

The names in the braces are sorted, and a line too long for 100 columns puts one name per line.

What jadpo check reports

Each of these comes with the edit that fixes it:

  • import.missing: a name used without its import.
  • import.unknown: a line naming a folder, domain or name that isn't there. A name imported from the wrong folder gets the edit that moves it to the right one.
  • import.unused: an import the file doesn't use.
  • import.unneeded: an import of a built-in, of the file's own declaration, of its test subject's, or of its own domain.
  • import.duplicate: a name or folder written twice.

Using another domain's private name is still visibility.private_cross_domain where the file uses it. A call that reaches nothing is still reported by name resolution, as an unknown name or callee, not as an import problem: Jadpo never asks you to import something the file can't use.

jadpo fmt fixes imports, then formats, by applying those edits, once every file in the project parses. jadpo fmt --check fails on a file whose imports it would change.

Edge cases

  • A misspelling is one error. While a name the file writes names nothing, no import is called unused, since the name may be a misspelt import, and jadpo fmt removes none either.
  • Before a promotion. A declaration in a file named after another, such as SnoozeDays beside snooze_todo, comes in from the folder its file is in (use planning/actions { SnoozeDays }) while layout.promotion_required asks for the move. The move's edit makes it, and jadpo fmt then moves each import to the name's new folder. jadpo fmt --layout does both in one step.
  • Loose files have no layout, so there are no folders to import from. Every name in them is seen without a use line, and a use line there is import.unknown.
  • A migration's changes.jadpo, which jadpo migrate new writes and which names what changed (Todo.rank: { ... }), imports nothing either.

Markdown for agents: /docs/imports.md.Built from Jadpo main at a707efb.