This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Dito.js is a declarative web framework with two main components: Dito.js Server (API-driven development with Koa.js/Objection.js) and Dito.js Admin (Vue.js admin interface). This is a monorepo managed by Lerna and pnpm workspaces.
- packages/server/: Server framework with models, controllers, middleware, and CLI
- packages/admin/: Vue.js admin interface with forms, types, and schema components
- packages/ui/: Shared Vue.js UI components and styles
- packages/utils/: Utility functions for arrays, objects, strings, dates, etc.
- packages/router/: Lightweight routing library
- packages/build/: Shared build configuration
# Install dependencies and build all packages
pnpm install
pnpm run build
# Watch mode for all packages (development builds)
pnpm run watch
# Build specific package
cd packages/admin && pnpm run build
cd packages/ui && pnpm run build# Run all tests
pnpm test
# Tests use Vitest with globals enabled# Run all linters
pnpm run lint
# Fix linting issues
pnpm run lint:fix
# Individual linters
pnpm run eslint
pnpm run stylelint
pnpm run penere # Prettier via penere# Run command across all packages
pnpm -r run <command>
# Clean all dist directories
pnpm run clean- Server: Koa.js, Objection.js, Knex.js, AJV schema validation
- Admin/UI: Vue 3, Vite, TipTap (rich text), Vue Router
- Database: Objection.js ORM with Knex.js query builder
- Build: Vite for frontend packages, ESLint + Stylelint + Penere (Prettier)
- 80 character line limit enforced by ESLint
- PascalCase for Vue components
- camelCase for props and variables
- kebab-case for Vue slots
- Vue attribute hyphenation disabled (use camelCase)
- Pug templates supported in Vue files
- ESM modules throughout (type: "module")
Dito Admin and UI packages use strict BEM methodology:
- Blocks:
.dito-[block](e.g.,.dito-button,.dito-table) - Elements:
.dito-[block]__[element](e.g.,.dito-label__prefix) - Modifiers:
.dito-[block]--[modifier](e.g.,.dito-buttons--large)
State is always represented through block-specific modifiers:
.dito-menu__link--active(not.dito-active).dito-pulldown--open(not.dito-open).dito-container--disabled(not.dito-disabled).dito-input--focus(not.dito-focus).dito-button--selected(not.dito-selected)
Only these classes remain as utilities:
.dito-scroll,.dito-scroll-parent- Scroll container infrastructure.dito-layout--vertical,.dito-layout--horizontal- Layout direction
Why these remain as utilities:
- Same behavior everywhere (no per-block overrides or variations)
- Well-defined contracts (infrastructure patterns)
- Single responsibility (manage specific cross-cutting concerns)
- No coupling or specificity issues
All other styling uses strict BEM. No shared utilities with overrides.
Schema values map to CSS modifiers programmatically:
layout: 'horizontal'→.dito-layout--horizontalpadding: 'nested'→.dito-pane--padding-nested- Column names →
.dito-column--{name},.dito-cell--{name}
Width/flex behavior is block-specific:
.dito-component--fill,.dito-component--grow,.dito-component--shrink.dito-label--fill,.dito-label--grow,.dito-label--shrink.dito-select--fill
Managed via getLayoutClasses(prefix) helper method in DitoContainer.
When building applications with this framework:
src/
├── server/ # Server application
│ ├── models/ # Model classes
│ └── controllers/ # Controller classes
├── admin/ # Admin view declarations
└── config/ # Configuration files
migrations/ # Database migrations
seeds/ # Database seeds
- Uses pnpm with workspaces
- Husky for pre-commit hooks with lint-staged
- TypeScript definitions available for all packages
- Supports linking to local Objection.js/Knex.js for development
- Admin package uses Vite for bundling with Vue 3 + TypeScript support