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: External services

External services

Two versions side by side, lazy loading and the package cache

How an app holds two major versions of one package while it moves between them, and how Jadpo avoids compiling and checking package code the app doesn't use.

  • When names carry the version. Exactly while the project holds two versions of one package of the same kind, both installed in packages/<name>/ or both the app's own in shared/providers/<name>/: then every name written through either carries its version (Postcodes.v3.UkPostcode, Postcodes.v3.uk.parse(...)), and one without it is package.version_needed, naming both. With one version held, a name never carries it, so there is one way to write each name; one that does is package.version_unneeded, with the edit that drops it. An installed package and the app's own of one name stay a clash (package.name_taken), never two versions. Two versions are two packages throughout: their declarations never clash, their failures are told apart, and the graph and the interpreter know each version's declarations by its own name (Postcodes.v2.uk.parse beside Postcodes.v3.uk.parse). A package's own code still writes its names bare. A name the package declares that looks like a version (a library called v2) is the declaration, not a version.
  • The use line. use packages/postcodes names the folder, so it brings in every version held there; there is no use line per version.
  • The lock and connections. Each version has its own line, as Postcodes.v2 and Postcodes.v3, sorted by name, then major version (Records and manifest). A connection names one version in package:, so two versions of a provider are two connections.
  • The commands. A package's folder or code name (postcodes, Postcodes) names both versions, so jadpo package show, update, remove and unlink refuse it and ask for the version (cli.package_arguments). add installs a second major version beside the first. remove refuses a version while the app's code writes a name through it (install.in_use), not while the use line stays for the other version. update's review marks an entry used by the app when the code writes it through that version.
  • Translations side by side. The app words a library package's messages under its folder's name (postcodes: { }, Packages' text in an app), which two versions would share, so while two are held the version joins the key (postcodes_v3: { }), as it joins the names; with one held, the key stays the folder's name.
  • Lazy loading. A package's index and provider.jadpo are always read; an installed package's resources/<resource>.jadpo is compiled only once code outside every package writes <connection>.<resource> for a connection to it. Its bytes still count towards the digest, so a changed resource the app doesn't call is still package.digest_mismatch. The app's own integrations are its code, compiled whole, and so are an installed package's types, failures and libraries, which the app's names reach directly. Once reached, a resource stays compiled for the life of jadpo dev, test --watch or the language server. jadpo package show reads a package whole.
  • The package cache. jadpo check keeps an installed package's check in ~/.cache/jadpo/packages/<digest>/<compiler> (under $XDG_CACHE_HOME when it is set): the paths of the package's source files it checked with no problem. A later check skips those files' own checks; their declarations are still read for the app's. The compiler is its version and the size and modification time of the running jadpo, so a rebuilt compiler never trusts an older one's check. Only a package whose files match its lock line's digest is cached, never a link; with no home folder, or a cache that can't be read or written, every file is checked. The other commands check every file.
  • Connection names. A connection, to a package or a driver, named like one of the app's domains or libraries is semantic.duplicate_declaration at the connection in app.jadpo, under "Connecting in app.jadpo". A package's library isn't one of the app's, so it never clashes.

Markdown for agents: /docs/two-versions-side-by-side-lazy-loading-and-the-package-cache.md.Built from Jadpo main at a707efb.