Skip to content

Project Structure ​

There is no cap2UI5 project layout. cap2UI5 is a CAP plugin, so the project is your CAP project, and the plugin adds two things to it without putting a single file in your repository.

What your project looks like ​

An ordinary CAP project. The only cap2UI5-specific thing in it is the dependency and one directory:

my-project/
├── db/
│   └── schema.cds          # your entities
├── srv/
│   ├── catalog-service.cds # your services — untouched by cap2UI5
│   ├── apps/               # ← your cap2UI5 apps, one file each
│   │   ├── hello.js
│   │   └── books.js
│   └── server.js           # optional, and NOT touched by the plugin
└── package.json            # "@cap2ui5/cds-plugin": "^x.y.z"

examples/bookshop in the cap2UI5 repository is exactly this and nothing more.

What the plugin adds at runtime ​

CAP loads cds-plugin.js from every dependency that has one. On cds watch that gives you:

where it comes from
/sap/bc/z2ui5, /rest/root/z2ui5the roundtrip route, mounted behind CAP's own middleware chain. A GET on it answers with a page that embeds the whole UI5 frontend, so there are no frontend files to serve, copy or maintain
cap2ui5.Draftsa CDS entity contributed through package.json#cds.requires, so cds deploy creates it next to your own tables

None of this appears in your working tree. There is nothing to regenerate, no vendored folder, no sync pipeline. Upgrading is npm update @cap2ui5/cds-plugin.

srv/apps/ — the one directory that is yours ​

Every .js, .mjs or .cjs file in it is loaded once the runtime is up and CAP has served the model, so an app module may call cds.entities() at its top. A file is not special in any way: it just calls defineApp, and it may call it more than once. A module that fails to load fails the start, as a service implementation does.

cds add cap2ui5 creates a first one, srv/apps/hello.js, when the directory has none — with import or require, whichever module format the project's package.json declares.

js
// srv/apps/pick.js — two apps in one file is fine
import { defineApp } from "@cap2ui5/cds-plugin";

defineApp("ZCL_PICK",     class { /* … */ });
defineApp("ZCL_PICK_ONE", class { /* … */ });

The first argument to defineApp is the name on the wire — what ?app_start= takes and what client.nav_app_call() resolves. The file name is irrelevant.

To put apps somewhere else, point the plugin at it:

json
{ "cds": { "requires": { "cap2ui5": { "apps": "srv/my-apps" } } } }

See Configuration for the rest of the knobs.

Apps from a package ​

A dependency can bring apps of its own, and they run beside the project's — the way abap2UI5's samples run in the system they are pulled into. @cap2ui5/samples is one such package:

bash
npm add -D @cap2ui5/samples

A package says where its app modules are in its package.json, and names the plugin as a peer dependency, so that its apps and the project's run on the same one:

json
{
  "cap2ui5": { "apps": "srv/apps" },
  "peerDependencies": { "@cap2ui5/cds-plugin": "^0.4.0" }
}

The plugin finds such packages the way CAP finds its plugins: among the project's dependencies, and outside production among its devDependencies too — so npm add -D brings a package's apps to development only. They load after the project's own apps, and the log names every package it loaded apps from. An app whose name the project already uses stays the project's, with a warning.

Where the framework actually lives ​

In node_modules, in two packages, and you own neither:

@cap2ui5/cds-pluginthe plugin — about 1,050 lines in 0.1.0, of which about 640 are code. cds-plugin.js, index.cds, index.js, lib/
@abap2ui5/node-runtimeabap2UI5 itself: upstream's ABAP, downported and transpiled over open-abap, with the UI5 frontend embedded in the page its GET answers with. The plugin pins one exact release

That split is the whole design. The plugin is a host: it mounts a route, implements the draft store over a CDS entity, and turns a JavaScript class into something the runtime can call. It contains no framework logic, which is why it cannot drift from abap2UI5 — see Architecture.

The repository is not the product

cap2UI5/cap2UI5 holds plugin/ (the package), examples/bookshop (a project that uses it) and runtime/ (a stand-in for @abap2ui5/node-runtime that the repository's own tests build from upstream). You consume the packages from npm; you do not clone the repository — unless you are working on cap2UI5 itself.

Next ​

Released under the MIT License.