Skip to content

Repository files navigation

AdonisJS Studio

Desktop app that scaffolds AdonisJS v7 projects from a card-based stack picker and saves lineups as one-click templates. Electron + electron-vite + React 19 + Tailwind v4 + shadcn/ui (Radix), laid out like the Aiven console.

What it does

  • New project: pick a starter kit (react, vue, hypermedia, api, api-monorepo), then database, auth guard, social login, storage, mail, extras and AdonisJS Plus feature packs as trading cards. Pack cards run nothing at create time: they need the Flow card, build on the auth pack (social auth also on a social login card), and Studio writes the /flow-apply order and prerequisites into STUDIO.md for the coding agent, plus a note step in the plan. The right panel shows the formation, the package count and the exact commands.
  • Create runs create-adonisjs in the folder you picked, then node ace add … for each card with --package-manager and --verbose (@adonisjs/drive --services … --install, @adonisjs/mail --transports, redis, transmit, bouncer, i18n, @adonisjs/otel, @tuyau/superjson, limiter and locks with --store=redis|database). The SuperJSON card also installs superjson (a direct dependency for the Luxon DateTime recipe file) and, on Inertia kits, adds plugins: [superjson()] to inertia/client.ts: the middleware only acts on requests the client plugin marks with x-superjson. File storage is a multi-pick: every disk gets a service in config/drive.ts and DRIVE_DISK in .env picks the active one, so a stack can run on the local disk in development and a bucket in production. One disk goes through node ace add; several go through npm install @adonisjs/drive plus node ace configure @adonisjs/drive --services=fs --services=r2 --install (add flattens repeated flags, see ally below), with the local disk first so DRIVE_DISK starts on it. A drive-config patch follows R2 and Supabase: the drive 4.0 config stub has no Supabase service block and no supportsACL: false for R2. With several disks a drive-env patch runs after the .env values are written: the drive configure makes every key required, so the keys the standby disks still miss become Env.schema.string.optional() in start/env.ts and read with an empty default in config/drive.ts, and the app boots on the local disk before the bucket has credentials. On the API kits the mail card is preceded by node ace add edge (built into core): their mail provider has no template engine, so message.htmlView() would throw. The hypermedia kit gets two Edge plugin cards, icons (edge-iconify + Heroicons) and Markdown (edge-markdown, Node 24), registered in a start/view.ts preload the patch adds to adonisrc.ts. Cache and queue configure always prompt for a driver and have no flag, so the runner answers the prompt on stdin (\033[B is arrow down, \n Enter). Ally goes through node ace configure --providers=a --providers=b because add flattens repeated flags (add.js, #configurePackage calls .toString() on the array). Health checks run node ace configure health_checks plus a patch for the routes and start/health.ts (database, connection count on Postgres / MySQL, Redis). Access tokens and basic auth are added next to the kit's session guard by editing config/auth.ts and the User model: re-running the auth configure would skip both files and write a second users migration. The Redis card also becomes the store for limiter, cache, locks and queue; without it they use the database and get migrations, which run right away on SQLite / libSQL. It installs Tailwind / daisyUI on Inertia kits and shadcn/ui on the React kit, switches the database with the official node ace configure @adonisjs/lucid --db=… --install --force (Postgres / MySQL / MariaDB as mysql / SQL Server / libSQL) and then sets the DB_* values compose.yml starts with plus the TLS options SQL Server needs locally, writes Docker files (with Redis and Jaeger services for those cards; the image installs with --ignore-scripts because the kits allow better-sqlite3's install script and better-sqlite3 13 keeps a binding.gyp without one, so npm would run node-gyp in an image that has no Python, while its prebuilt binaries already sit in the tarball), runs node ace codegen and drops a STUDIO.md plus a CLAUDE.md that points at it. Everything streams into the log. On the API monorepo kit the ace steps run in apps/backend: npm 11 finds the workspace root from there, so every node ace add lands in the root node_modules and lockfile (verified card by card), but it ignores an .npmrc inside apps/backend, so the Plus registry scope and ally's legacy-peer-deps are written to the root .npmrc. The Docker card works there too (npm only for now): installs run from the root with npm ci --workspace apps/backend, the build inside the app, and the image gets the root node_modules next to apps/backend/build; compose.yml reads apps/backend/.env. The scenarios in src/shared/recipe.ts are checked against the packages' own configure scripts.
  • With ally in the lineup and npm as the package manager the project gets .npmrc with legacy-peer-deps=true: ally 6 still peers on inertia v4 while the v7 kits ship inertia v5.
  • Keys and connections: cards that need credentials (Sentry, Stripe, mail providers, storage buckets, social login, Postgres/MySQL) open a dialog with a short how-to, the exact env variables and a "Provide later" button. Values are written into the new project's .env only and never saved with a template. Create runs a last check for cards that are still missing keys.
  • Environments (top nav): named sets of API keys shared by every workspace, e.g. "Personal" and "Client X". Tick "Keep in …" in the keys dialog and the next project that picks the same card is filled in without asking; "Create project" on a template uses the default environment, so that dialog only asks for a name and a folder. The page lists every variable with the cards that use it, imports a .env file (known keys pre-ticked) and lets you add custom keys, which go into every project created with that environment. Values are sealed one by one with Electron's safeStorage (macOS Keychain, Windows DPAPI, GNOME Keyring / KWallet on Linux) and kept in environments.json (mode 0600) in the app's user data folder. Without a keychain they are stored as plain text and the page says so. The main process merges the environment into the create job, so the renderer never ships the values for a create.
  • STUDIO.md and CLAUDE.md: the last create step writes STUDIO.md into the new project: the stack, what every step did (done / skipped / failed), and a setup checklist with - [ ] boxes split into Agent tasks (code an AI agent can do: Persona mixins, Permissions migrations, ally routes, wiring Stripe or Sentry, the first i18n translation files, the SuperJSON DateTime recipe, the monorepo frontend, redoing a failed step), Needs the user (every key a card asks for with its state, never the value, plus databases and services that must run), and Before production. CLAUDE.md is created, or appended to when Flow or the kit wrote one, and tells the agent to read STUDIO.md, skip [x] items, do the agent tasks and ask for the rest instead of inventing values.
  • AdonisJS Plus: three Extras cards (Persona, Permissions, Flow) install the real @adonisplus/* packages from the private registry at plus.adonisjs.com. Picking one asks for a Plus access token once; the project gets @adonisplus:registry=… in .npmrc (safe to commit) and the token goes into ~/.npmrc on your machine, exactly what npm config set does. Permissions pulls in Bouncer and runs node ace configure @adonisplus/permissions; Flow runs node ace flow:install for Claude Code with the stack matching the kit, every prompt answered by a flag (--workflow included: without it the command waits for a confirm the runner cannot answer) and, on the monorepo kit, Enter on stdin for the workspace-root prompt. With the Docker card the Dockerfile copies .npmrc, mounts the token as a BuildKit secret (NPM_TOKEN) around each install and removes .npmrc in the same RUN; compose.yml passes the secret from the environment. The run line in STUDIO.md reads the token from ~/.npmrc with sed: npm 11 refuses npm config get on _authToken keys ("option is protected"), which the Plus docs still suggest.
  • Templates: save any lineup, create from it with just a name and a folder, edit, duplicate, export / import as JSON.
  • Community: a registry of shared lineups (bundled samples until you set a registry URL in Settings), copy to mine or use directly.
  • Projects: run / stop the dev server, open in your editor, reveal, open a terminal.
  • Deploy and Admin dashboard are roadmap placeholders.

Run it

Needs Node 24 and npm 11. Tested on Ubuntu 24.04; npm run dev should work on macOS and Windows as well (untested), packaged builds are not published yet.

git clone https://github.com/campar/adonisjs-studio.git && cd adonisjs-studio
npm install            # postinstall runs install-electron: electron 44 ships no postinstall of its own
npm run dev            # electron-vite with HMR (Ubuntu: npm run dev:linux, see below)
npm run build          # bundles to out/
npm run package:linux  # AppImage + deb (also package:mac, package:win)

# screenshots without touching real settings
ADONIS_STUDIO_USER_DATA=/tmp/studio-ud ADONIS_STUDIO_SMOKE=/tmp/shot.png ADONIS_STUDIO_SMOKE_PAGE=projects npx electron . --no-sandbox

On Ubuntu 24.04+ the Chromium sandbox helper needs to be SUID for a dev run:

sudo chown root:root node_modules/electron/dist/chrome-sandbox
sudo chmod 4755 node_modules/electron/dist/chrome-sandbox
# or, for local development only:
npm run dev -- -- --no-sandbox

Layout

src/shared     catalog (cards), recipe (lineup → steps), types
src/main       Electron main: window, IPC, job runner, file patches, dev servers, stores
src/preload    contextBridge API exposed as window.studio
src/renderer   React app: shell, lineup cards, pages, shadcn/ui components

Data lives in Electron's userData folder as settings.json, templates.json and projects.json.

About

Desktop app that scaffolds AdonisJS v7 projects from a card-based stack picker and hands the setup to your coding agent

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages