Skip to content

Code extensions ​

What is it? ​

Most of an application is configuration. When configuration is not enough you add code, in the language that suits the job:

WhereLanguagesUsed for
BackendJava, Python (FastAPI), Node.js (Express / TypeScript), Go (net/http)logic, calculations, integrations, custom APIs
FrontendReact (TypeScript)custom blocks and screens that no built-in block can express

Backend code runs either embedded in the platform (Java only) or as its own service container in any of the three languages. See Backend services.

When should I use configuration and when code? ​

NeedUse
New data, screen, form, menu, reportconfiguration
Validation, computed field, approvalconfiguration (rule, workflow)
Change a shipped pagelayered override
Reaction when a record is savedextension point bound to a service
Heavy calculation, third-party library, custom protocolbackend code (Java, Python, Node.js or Go)
A screen or widget no block can expressReact custom block

Start with configuration. Add code only for the last two.

What Studio does for each language today ​

LanguageStartEditCompile / test / package in StudioRun
JavaBuild, Add Java backend (starter)Advanced, Java source; or source-writeyes: Compile, Run tests, Packageembedded, or a service container controlled from Studio
Node.jsplatform-cli service-plugin:scaffold --id <id> --runtime nodejs --out <dir>, or MCP erp_service_plugin_scaffoldsource-write (CLI, MCP)install, test, build through Node: runservice; self-registers with the platform
Pythonthe same scaffold with --runtime python (FastAPI)source-write (CLI, MCP)run pytest yourself for now; a Studio Python build step is Plannedservice; self-registers with the platform
Reactwrite a .tsx blocksource-write, then erp plugin compile <file.tsx>compile to a page/block artifact with the Code Plugin SDKrendered by the platform like any block

Every language talks to the platform the same way: plain REST with the tenant and user in the request headers, and a shared secret to self-register. A Python, Node.js or Go service is therefore a first-class citizen, even where Studio's own build buttons cover only Java and Node.

Read and write source from the command line or an agent ​

bash
erp source files --plugin-id leave-management
erp source read  --plugin-id leave-management --path service/app/main.py
erp source write --plugin-id leave-management --path service/app/accrual.py --file ./accrual.py
erp source write --plugin-id leave-management --path frontend/LeaveCard.tsx --file ./LeaveCard.tsx
erp plugin op java-compile --plugin-id leave-management

The same three operations are MCP tools (erp_plugin_op with source-files, source-read, source-write), so an AI coding assistant can write Java, Python, Node.js and React into a plugin and use the compile and test operations to check its work. Paths are relative to the plugin folder; the plugin's own metadata and build output are never touched, and only source and config file types are accepted.

Build, dependencies, debugging, logging ​

Java builds run in an isolated container against the libraries in the build image; Node builds can fetch npm packages. A library the worker image lacks needs adding to the image. Compile and test output is in the Output panel. A service's live logs are in Deploy, Manage backend service. Use each language's normal logging; the tenant is attached to each request.

Planned (placeholders) ​

Python build, test and deploy buttons in Studio; Node and Python starters in the Create Plugin wizard; remote debugging; publishing the React component SDK for use outside the repository. Planned.

Common mistakes ​

Reaching for code when a rule does it; a Java library missing from the worker image; forgetting that a service is a separate container (memory, restart); writing metadata files with source-write (use the artifact operations instead).

Plugin designer, Testing, AI assistant.