Product help

How appshare fits together.

appshare lets a team publish mini apps as static frontends while the server provides the shared project services: data, files, business functions, audit, policies, SDKs, MCP, and controlled publication.

The short version

Build the UI with the Appshare SDK, keep sensitive business logic in Project Functions, publish to dev first, then promote to prod when the project owner is ready.

ConceptsProjects, folders, environments, roles. BuildBootstrap lane, React lane, SDKs. SecurityRuntime policies, PII audit, secrets. AgentsCodex, MCP, generated SDKs.

01

Core concepts

Project

The ownership boundary. Tables, storage, functions, policies, keys, logs, webhooks, and publications belong to a project.

Environment

dev, test, and prod isolate data and services. Codex should use dev by default.

Folder

A published app URL under /f/{folder}/. One project can publish multiple folders that share the same project services.

Runtime profile

A business role such as admin, guest, or legal. It controls what the running app can do.

02

Recommended workflow

  1. Create or select a project in the console.
  2. Build the mini app using the Appshare SDK rather than raw REST calls.
  3. Write sensitive or identity-dependent business logic as a Project Function.
  4. Publish the folder to dev and test with realistic server data.
  5. Configure runtime policy, folder visibility, and allowed runtime profiles.
  6. Promote explicitly to prod when the app is ready.

Do not use browser storage as the source of truth for business data. Use project tables, project storage, or functions.

03

Managed services

Tables

Project tables store JSON rows per environment. Schemas can validate shape, generate SDK types, and mark PII/privacy metadata.

Storage

Project storage keeps files separate from published app assets. Buckets are environment-scoped and controlled by runtime policy.

Project Functions

Functions are small server-side JavaScript handlers for business logic. They receive a safe ctx and cannot access Node APIs, filesystem, network, or secrets directly.

Email, LLM, jobs, and webhooks

Email and LLM calls are logged and quota-controlled. Jobs handle async work such as imports/exports. Webhooks emit signed events with delivery history.

04

Frontend lanes

Bootstrap lane

Use HTML, vanilla JS, Bootstrap, /sdk/appshare.js, and /sdk/appshare-ui.js. This is the default for CRUDs, dashboards, forms, and master-detail modals.

React lane

Use React only for advanced state, nested editors, rich interaction, or reusable components. Keep the stack closed and use the Appshare React Kit.

const appshare = Appshare.create({
  projectId: "prj_...",
  environment: "dev"
});

const rows = await appshare.table("orders").list({ limit: 50 });
const result = await appshare.function("mis_incidencias_pendientes").invoke({ limit: 20 });

05

Security model

Administrative roles

Project owner, editor, and viewer control who can manage the project from the console and APIs.

Runtime policies

Runtime policies control what the app can do at runtime: list/view/create/edit/delete table rows, invoke functions, call email/LLM, create jobs, access storage, or trigger webhooks.

Folder profile gates

A folder can set allowed_runtime_roles. For example, a public folder may still be available only to profile legal.

PII and privacy levels

Table schemas can mark fields with pii, x-pii, privacy_level, and pii_category. When a response exposes PII, appshare writes an audit log of who accessed which field classes.

Secrets

Secrets are stored server-side and returned only as redacted metadata. Browser apps, generated SDKs, REST responses, and MCP tools must not expose secret values.

06

Agents and MCP

Codex and other agents should use project-aware MCP tools such as publish_app, promote_project_app, upsert_project_function, create_project_job, and generate_project_sdk.

Use LLM instructions for machine-readable guidance. Use this page when a human needs the product model.

Project API keys use the hpk_... prefix, are scoped to one project, and should include only the scopes needed by the agent or integration.

07

Example: pending incidents

If an app needs "my pending incidents", do not download all incidents to the browser and filter there. Create a Project Function that receives ctx.user, reads the allowed rows server-side, and returns only the safe result.

The repository includes a complete reference app at examples/pending-incidents/ with frontend files, Project Functions, schema, runtime policy, seed data, publish payload, and import job mapping. The public gallery is available at /examples.

function handler(event, ctx) {
  return ctx.tables.list("incidents", {
    where: { assignee_email: ctx.user.email, status: "pending" },
    limit: event.limit || 50
  });
}