Before you start
Install these first:
The Darpan repositories are public, and the clone commands below use HTTPS URLs that need no sign-in. If a clone returns
Repository not found, check the repository name before changing anything else.
Folder layout
This guide creates this layout:darpan-backend is a checkout of Darpan’s Moqui framework fork. The Darpan backend code lives inside darpan-backend/runtime/component/**.
Moqui 4 uses the embedded Bitronix transaction manager. The old
moqui-atomikos component is retired and is no longer cloned or built.Set the JDK 21 runtime flags
The backend JVM needs a set of--add-opens flags (the canonical Spark 3.5 / JDK 21 list) plus a couple of agent and native-access flags. Spark fails without them. Export them in the shell you will use for every backend command (load, run, and npm run dev:stack). Neither ./gradlew run nor npm run dev:stack sets them for you:
Clone the backend
Create a parent folder and clone Darpan’s fork of the Moqui framework asdarpan-backend:
drpn-ai/moqui-framework fork, not upstream moqui/moqui-framework. The fork is upstream Moqui 4 plus the embedded Bitronix transaction manager and a sign-in fix: without that fix, a sign-in can wait on itself for a database lock until the lock times out.
The production images also apply a small
build.gradle patch, docker/buildGradle.patch in darpan-docker-config, which adds a Spark export flag to every Gradle-forked JVM. Local development does not need it as long as JAVA_TOOL_OPTIONS is exported.Clone the backend components
Clone the required runtime components intoruntime/component:
moqui-sftp is needed by the Darpan component build and test classpath. The five Darpan components provide the core backend, Shopify integration, NetSuite integration, HotWax integration, and database sources. Without database-darpan, the database source that the seed data registers fails at extraction.
The hosted images also carry moqui-gql, a GraphQL component that is not a supported public API yet. It is optional locally. If you clone it, build its jar before the first load, because nothing else in the build triggers it and the backend fails at startup without it:
Load local setup data
Fromdarpan-backend, load the framework and Darpan setup data:
load runs with types=all, so it loads every data file in dependency-safe order, including the framework seed data and Darpan’s custom darpan-seed-initial (type definitions) and darpan-seed (setup records) files. The first load can take several minutes because Gradle also resolves backend dependencies and builds the components. Local development uses Moqui’s embedded H2 database, which allows one process at a time.
./gradlew :runtime:component:darpan:loadDarpanUpgradeData is a different command. It is the upgrade step for existing environments: it reloads every Darpan seed file of type darpan-seed (an idempotent upsert), and it reads the production configuration and the built runtime WAR by default. It is not a substitute for ./gradlew load on a fresh setup.Clone the UI
Go back to the parent folder and clone the Darpan UI:.env file. When no API URL is configured, Vite proxies /rpc/json to http://localhost:8080.
Start the stack
Start backend and frontend together fromdarpan-ui:
If your backend folder is somewhere else, pass the path explicitly:
8080 or 5173 is already in use, the helper tries to stop the existing listener before starting the new stack.
Sign in locally
Open the UI:http://localhost:5173/login and sign in with the same username and password.
Do not use local development credentials in hosted or shared environments.
Confirm the setup
After sign-in, confirm these checks:- The Darpan UI opens at
http://localhost:5173. - The backend login page opens at
http://localhost:8080/Login. - The app can sign in without a
No active authenticated sessionloop. - Ask Darpan opens with
Cmd/Ctrl+Kor by clicking Tara (the red panda in the corner). - Open User Settings loads from the local backend.
- Open Runs Settings or Create Reconciliation Flow loads without API errors.
Daily startup
After the first setup, the normal development startup is:./gradlew load every day. Rerun it when seed data changes, the local database is missing, or a backend change explicitly requires a reload. Keep JAVA_TOOL_OPTIONS exported in the shell each session.