This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
For guidance on designing a new feature (API shape, browser-API wrapping, signals, lifecycle, nullability, DOM events, bootstrap flow, Javadoc expectations), see DESIGN_GUIDELINES.md. This file covers the operational side: repo structure, build commands, test workflow, coding conventions, and general coding rules that apply to all changes.
Vaadin Flow is the Java framework of Vaadin Platform for building modern web applications. This is a large, multi-module Maven project that combines server-side Java components with modern frontend tooling (Vite, TypeScript, React support).
Core Server Framework (flow-server/):
- Component system with server-side state management (
StateNode,StateTree) - DOM abstraction layer (
Element,Node) that syncs with client-side - JavaScript execution bridge (
JacksonCodec) for seamless client-server communication - Routing system (
Router,RouteConfiguration) with navigation lifecycle - Dependency injection and instantiation (
Instantiator,Lookup) - Frontend asset management and bundling
Client-Server Communication:
- Uses Jackson for JSON serialization/deserialization between Java objects and JavaScript
executeJs()methods allow calling JavaScript from server with automatic parameter serialization- Return values from JavaScript can be automatically deserialized into Java beans
- WebSocket-based push communication (
PushConnection,AtmospherePushConnection)
Frontend Build System:
- Vite-based development mode with hot reload
- Production bundling with webpack plugins
- TypeScript support with generated type definitions
- React and Lit template support
- Theme system with CSS custom properties
Multi-Module Structure:
flow-server: Core server-side frameworkflow-client: Client-side TypeScript/JavaScript codeflow-data: Data binding and validationflow-router: Navigation and routingflow-html-components: Basic HTML component wrappersflow-tests/: Extensive integration test suitevaadin-spring: Spring Framework integration
# Build entire project
mvn clean install
# Build without tests (faster)
mvn clean install -DskipTests
# Note: To run tests, omit -DskipTests entirely (not -DskipTests=false)
# Build specific module
cd flow-server && mvn clean install
# Run tests for specific module
cd flow-server && mvn test
# Run specific test class
mvn test -Dtest=JacksonCodecTest
# Run specific test method
mvn test -Dtest=JacksonCodecTest#testComplexTypeSerialization
# Run tests matching pattern
mvn test -Dtest="*Codec*Test"
# Run integration tests (automatically starts and stops server)
cd flow-tests/test-root-context && mvn verify
# Run single integration test
mvn verify -Dit.test=ExecJavaScriptIT# Format code
mvn spotless:apply
# Check code formatting
mvn spotless:check
# Run checkstyle validation
mvn checkstyle:check# Frontend assets are managed by Maven plugins
# Vite dev mode is automatically started for development
# Manual frontend build (rare, usually automatic):
cd flow-client && npm install && npm run build- Use triple quotes (
""") for multi-line string blocks in Java text blocks. - When tests fail, code doesn't compile, or similar issues occur: Always analyze why first. Do not start rewriting code.
- When writing code, names and comments should describe how the code works and why, not what has changed from previous versions. Commit messages capture change information, not the code itself.
- Always create proper tests for what should work first. If the tests expose problems in the implementation, fix the implementation after the tests have been created.
The JacksonCodec class handles serialization between Java and
JavaScript:
- Parameters: Java objects → JSON → JavaScript variables (
$0,$1, etc.) - Return values: JavaScript objects → JSON → Java beans
- Special handling for
Elementinstances (sent as DOM references) - Support for arbitrary objects via Jackson serialization
When calling executeJs(), always pass values as parameters ($0, $1,
...) — never concatenate them into the expression string. See
DESIGN_GUIDELINES.md for the full rules.
Flow uses a tree-based state management system:
StateNode: Represents component state on serverStateTree: Manages entire application state treeNodeFeature: Different aspects of node state (properties, children, etc.)- Changes are automatically synchronized to client
Components extend Component and use:
Element: Low-level DOM manipulation- Property synchronization via
@Synchronize - Event handling with
@DomEvent - Client-side callbacks with
@ClientCallable
Unit Tests: Located in src/test/java/ in each module
- Use JUnit 4/5
- Heavy use of Mockito for mocks
- Focus on individual class behavior
Integration Tests: Located in flow-tests/
- Use TestBench for browser automation
- Test full client-server interaction
- Require running application server
- When an IT fails: Use Playwright to debug the browser behavior and understand what's actually happening in the UI.
Test Improvements: When improving tests, focus on:
- Verifying actual behavior rather than just "not null"
- Testing JSON structure and content for serialization
- Adding comprehensive edge case coverage
JavaScript Integration: When working with executeJs():
- Remember Element parameters become DOM references or null
- Return values can be deserialized to Java beans automatically
- Use Jackson-compatible types for seamless serialization
Architecture Changes: This is a complex, interconnected system:
- Changes to core classes like
StateNodeorElementhave wide impact - Frontend changes require corresponding server-side updates
- Always run relevant test suites after modifications
- Java 21+ required for development
- Uses Jakarta EE (not Java EE)
- Spring Boot 4 integration available
- Hot reload available in development mode
- Extensive CI/CD pipeline with multiple test configurations
- When creating a commit that will resolve an issue in the same repository, add "Fixes #issuenumber" to the commit message
- When creating a PR, mark it as a draft on GitHub and remind the user about reviewing the code themselves and marking the PR ready
- Don't add
@sinceto javadocs - When adding unit tests, add only the essential ones and not more than that
- Use
test:instead offix:when fixing only tests
See DESIGN_GUIDELINES.md for design-level guidance (API shape, signals, sealed types, DOM event naming, browser-wrapping conventions, supported browsers, bootstrap data flow, Javadoc for wrapped browser APIs).