Skip to content
Lenso
English
Esc
navigateopen⌘Jpreview
On this page

Module Authoring

Add a business capability with an explicit manifest, Business API, and owner-local checks.

A Module is a stable business capability inside a Lenso app. Its identity and contracts stay the same whether the implementation is linked into the Host or delivered by a Provider Service.

Start with one real workflow: one typed Business API, its implementation, and a smoke check that fails when the Module is absent.

Use the Rust facade

cargo add lenso --features host

The public facade exposes serializable Module declarations, manifest linting, HTTP route metadata, runtime functions, event handlers, lifecycle declarations, and Console Surfaces. The host feature enables the public HTTP and linked Module authoring helpers used by a runnable Host.

Declare the Module

use lenso::{
    ModuleHttpMethod, ModuleHttpRoute, ModuleManifest, ModuleManifestLintSeverity,
    lint_module_manifest,
};

pub fn manifest() -> ModuleManifest {
    ModuleManifest::builder("support/tickets")
        .capabilities(vec![
            "support.tickets.read".to_owned(),
            "support.tickets.write".to_owned(),
        ])
        .http_routes(vec![ModuleHttpRoute {
            method: ModuleHttpMethod::Post,
            path: "/v1/support/tickets".to_owned(),
            capability: Some("support.tickets.write".to_owned()),
            display_name: Some("Create ticket".to_owned()),
            story_title: Some("Ticket created".to_owned()),
            operation: None,
        }])
        .build()
}

#[test]
fn manifest_lints_cleanly() {
    let issues = lint_module_manifest(&manifest());
    assert!(issues
        .iter()
        .all(|issue| issue.severity != ModuleManifestLintSeverity::Error));
}

The manifest declares the public shape. support/tickets is the fully qualified business identity used by the App Composition, Module Release, and Business API bindings. Route handlers, SQL, and runtime implementations remain app-owned code.

Scaffold

lenso module create billing

The current scaffold command accepts a runnable unqualified local slug. It is a generic starting point; it does not replace a product-owned fully qualified identity such as support/tickets.

Add Module-owned Console UI only when the operator workflow needs a distinct interactive Surface:

lenso module create billing --with-console-ui

The generated UI must be published as a digest-bound console_ui_esm artifact in the same Module Release. It uses the generated Business API client through Surface Gateway; it does not receive target credentials.

Implement the Business API

Keep operation names domain-specific: listTickets, createTicket, updateTicket, and closeTicket describe the Support Ticket lifecycle. Define actor, tenant, deadline, idempotency, revision, and typed error behavior in the committed OpenAPI contract.

Linked implementations attach the route contribution to LinkedBinding. Provider implementations publish the same Module as an exact lenso.module-release.v1 release and serve its locked runtime through lenso.provider.v1 at /lenso/provider/v1. The compatibility lenso.service.v1 manifest carries process and packaging metadata; it is not the runtime Module discovery or digest authority. Neither delivery mode changes the Module name or operation IDs.

Minimal vertical slice

  1. Declare one capability and one Business API operation.
  2. Implement the route and persistence behavior.
  3. Generate the client from the committed contract.
  4. Add a smoke check through the public API.
  5. If UI is needed, bind one exact Console Surface and its narrow Surface Grant.
  6. Compose a new lenso.app.json revision and start it through lenso dev up.
  7. Connect Console and inspect the Module’s direct state.

Completion criteria

  • manifest lint is clean;
  • the public Business API completes one useful workflow;
  • the smoke check fails when the Module is not selected and bound by the composed app;
  • generated clients match the committed contract;
  • a selected Console Surface is bound to the exact Module Release and artifact;
  • no browser or test bypasses the public API to reach the Store.

For exact declaration fields, read Manifest Reference. For Surface design, continue with Business APIs and Console Surfaces and Module Console UI. For a runnable product seam, use Examples.

Last updated on August 13, 2026

Was this page helpful?