This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
evitaLab is the official web-based GUI client for evitaDB e-commerce database. It's a Vue.js SPA that allows users to browse entities, execute queries (GraphQL/evitaQL), inspect schemas, manage server connections, and more.
# Install dependencies
yarn install
# Run development server (localhost:3000/lab)
yarn dev
# Run in driver mode for evitaLab Desktop (localhost:3000)
yarn dev-driver
# Build for production
yarn build # Standalone mode
yarn build-driver # Driver mode for Desktop app
# Lint with auto-fix
yarn lint
# Run tests
yarn testEnvironment Configuration: Set VITE_DEV_CONNECTION in .env.local to DEMO (default) or LOCAL to change the dev connection target.
The codebase is organized into modules under src/modules/. Each module is a semantic domain separation with its own services, components, and models. Modules communicate via dependency injection.
Module types:
- Abstract modules (
base,console,code-editor): Shared services, models, and UI components - Generic modules (
config,connection,workspace,storage,keymap): Core evitaLab infrastructure - Feature modules (
entity-viewer,evitaql-console,graphql-console,schema-viewer, etc.): User-facing features
Key modules:
database-driver:EvitaClientclass - the single entrypoint for all evitaDB server communication. Uses gRPC internally but exposes an internal model tailored to evitaLabworkspace: Manages tabs, history, and overall UI structure. UseWorkspaceServiceto create tabsconnection: Manages connections to evitaDB instances
Modules that need dependency injection implement ModuleRegistrar interface and are registered in src/modules/modules.ts. The registration order matters - base modules must be registered before feature modules that depend on them.
// Example: injecting EvitaClient in a module registrar
const evitaClient: EvitaClient = builder.inject(evitaClientInjectionKey)
// In components, use the helper
const evitaClient = useEvitaClient()main.ts initializes Vue, plugins, and calls each module's register() method. Lab.vue is the root component.
- Use Single-File Components with Composition API
- Order:
<script>,<template>,<style> - Setup structure: imports → constants → service injection → props/emit → refs/computed/functions
- Complex data-accessing components should follow MVVM pattern with a mediator service
Export injection key and helper function for each injectable service:
export const serviceInjectionKey: InjectionKey<Service> = Symbol('service')
export function useService(): Service {
return mandatoryInject(serviceInjectionKey)
}For component tree injection, create a dependencies.ts file with provideX/injectX methods.
Use Vuetify components as the base. Custom components in modules/base/component:
VLabDialog/VFormDialogfor dialogsVTabToolbarfor tab toolbarsVPropertiesTablefor property displaysVMarkdownfor markdown renderingVQueryEditor,VInlineQueryEditor,VPreviewEditorfor code editors
Wrap all service/EvitaClient calls in try-catch and use useToaster().error(...) for user feedback.
Implement TabDefinition interface, create a factory class, then use:
workspaceService.createTab(tabDefinition)Document every new Vue component, class, type, interface, and so on.
master: Released versions onlydev: Current development (target for feature branches)- Feature branches: Created from
devfor each issue
Use conventional commits for commit messages - CI/CD depends on this for versioning.
Always use Context7 MCP when you need library/API documentation, code generation, setup or configuration steps without being explicitly asked.