This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Airframe is a collection of essential building blocks for developing applications in Scala, including:
- Dependency injection (DI) framework
- HTTP/RPC framework
- Object serialization (JSON/MessagePack)
- Logging framework
- Testing framework (AirSpec)
- SQL parser & analyzer
- Various utilities (metrics, control flow, JDBC, etc.)
This is a multi-module sbt project using Scala 3 as the default version, with cross-building support for Scala 2.12, 2.13, and Scala Native/JS platforms.
# Open sbt shell
./sbt
# Compile all JVM modules
./sbt projectJVM/compile
# Compile specific module (replace moduleName with actual module, e.g., log, surface, di)
./sbt "moduleNameJVM/compile"
# Run tests for all JVM modules
./sbt projectJVM/test
# Run tests for specific module
./sbt "moduleNameJVM/test"
# Run a specific test class
./sbt 'moduleNameJVM/testOnly *TestClassName'
# Run a single test case (AirSpec) - use quotes around test name pattern
./sbt 'moduleNameJVM/testOnly *TestClassName -- "test name pattern"'
# Compile for other platforms
./sbt projectJS/compile # Scala.js modules
./sbt projectNative/compile # Scala Native modules
# Switch Scala version
./sbt "++ 2.13" projectJVM/compile # Use Scala 2.13
./sbt "++ 2.12" projectJVM/compile # Use Scala 2.12
./sbt "++ 3" projectJVM/compile # Use Scala 3# Format all Scala code
./sbt scalafmtAll
# Format specific module
./sbt "moduleNameJVM/scalafmtAll"
# Check formatting without applying
./sbt scalafmtCheck
# Apply Scalafix rules
./sbt scalafixAllThis project uses AirSpec as the primary testing framework. Key assertion patterns:
shouldBe- equality assertionshouldNotBe- inequality assertionshouldMatch- pattern matching assertion
airframe/
├── airframe-*/ # Core modules (di, log, surface, codec, etc.)
│ ├── src/
│ │ ├── main/scala/ # Shared code across platforms
│ │ └── test/scala/ # Shared test code
│ ├── .jvm/ # JVM-specific code
│ ├── .js/ # Scala.js-specific code
│ └── .native/ # Scala Native-specific code
├── airspec/ # Testing framework
├── sbt-airframe/ # sbt plugin
├── examples/ # Example applications
├── docs/ # Documentation
└── build.sbt # Main build configuration
- JVM modules:
moduleNameJVM(e.g.,logJVM,surfaceJVM) - JS modules:
moduleNameJS(e.g.,logJS,surfaceJS) - Native modules:
moduleNameNative(e.g.,logNative,surfaceNative)
airframe-core- A new core module of Airframe for Scala 3airframe-di- Dependency injection frameworkairframe-log- Logging framework (minimal dependencies)airframe-surface- Object structure extraction
airframe-codec- MessagePack-based codecairframe-msgpack- Pure-Scala MessagePack libraryairframe-json- JSON parser
airframe-http- REST and RPC frameworkairframe-http-netty- Netty backendairframe-http-grpc- gRPC backendairframe-http-finagle- Finagle backend (Scala 2 only)airframe-http-okhttp- OkHttp client
airframe-sql- SQL parser & analyzerairframe-parquet- Parquet format supportairframe-jdbc- JDBC connection pool
airframe-control- Retry and control flow utilitiesairframe-metrics- Duration, size, time window representationsairframe-ulid- ULID generatorairframe-rx- Reactive stream interface
- Default: Scala 3
- Use Scala 2.13 compatible syntax for broad compatibility
- Scala 3 specific syntax only in
src/{main,test}/scala3directories - Platform-specific code in
.jvm/,.js/,.native/subdirectories
- Run
./sbt scalafmtAllbefore committing - Use
${...}for string interpolation (not$var) - Case classes for configuration should have
withXXX()andnoXXX()methods - Avoid
Try[A]return types - use plain exceptions or domain-specific errors
airframe-coreandairframe-logshould have minimal dependencies- Check existing
libraryDependenciesinbuild.sbtbefore adding new ones - Ensure dependencies are available for all target platforms (JVM/JS/Native)
- Use AirSpec framework for tests
- Test names should be concise and descriptive
- Avoid mocks to reduce maintenance cost
- Run tests sequentially for JMX-related modules to avoid registration conflicts
# Feature branch
git switch -c feature/$(date +"%Y%m%d_%H%M%S")-description
# Bug fix branch
git switch -c fix/$(date +"%Y%m%d_%H%M%S")-descriptionfeature:- New featuresfix:- Bug fixesinternal:- Non-user facing changesdoc:- Documentation updates
Focus on "why" not "what" in commit messages.
# Create PR
gh pr create --title "Title" --body "Description"
# Merge with squash (preferred)
gh pr merge --squash --autoCheck binary compatibility before releases:
./sbt mimaReportBinaryIssuesThe comparison baseline is set in AIRFRAME_BINARY_COMPAT_VERSION in build.sbt.
Releases are managed through GitHub Actions:
- Create release tag:
ruby ./scripts/release.rb - Artifacts automatically published to Maven Central
- Release notes generated via release-drafter
- Add module definition in
build.sbt - Follow existing module structure patterns
- Add to appropriate project aggregation (jvmProjects, jsProjects, etc.)
./sbt "benchmark/run"
./sbt "benchmark/jmh:run -i 10 -wi 10 -f1 BenchmarkClass"./sbt publishSnapshots./sbt publishAllLocal- JMX test failures: Tests in JMX-related modules run sequentially by default
- Scala 2.13 fork: Some tests fork JVM for Scala 2.13 compatibility
- Binary compatibility: Run
mimaReportBinaryIssuesto check compatibility