api-design

Design and review public Java APIs with interfaces, records, and module boundaries.

Updated Mar 7, 2026
One-click install
npx skills add https://github.com/OpenElementsLabs/claude-base --skill api-design-openelementslabs
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: api-design
Source: https://github.com/OpenElementsLabs/claude-base/tree/main/claude-project-base/skills/java-api-design
Command: npx skills add https://github.com/OpenElementsLabs/claude-base --skill api-design-openelementslabs

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Java library teams often struggle to publish public APIs that leak implementation details or hinder evolution. This skill guides you to design and review public Java APIs that hide implementations and use appropriate constructs (interfaces, records, enums, annotations) to maximize stability.

Core Features & Use Cases

  • Focus on minimal surface: expose interfaces and records, not concrete classes.
  • Enable safe evolution with factories, SPI, and modularization to support external consumers and long-term compatibility.
  • Use cases include designing a library API, refactoring toward SPI, selecting between interfaces vs classes, and structuring module boundaries for clean separation.

Quick Start

Outline a minimal, stable Java API design for a new library given a set of consumers and constraints.

Frequently Asked Questions about api-design

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I design a Java library API that hides implementation details?

To design a Java library API that hides implementation details, expose minimal public surfaces using interfaces and records instead of concrete classes. This approach maintains proper encapsulation and ensures long-term API stability for external consumers.

When should I use interfaces vs records vs enums for public Java APIs?

Use interfaces to define behavior contracts, records for simple data carriers, and enums for fixed constant sets in public Java APIs. Selecting the appropriate construct maximizes implementation hiding and establishes clear, stable module boundaries for external consumers.

What is the best way to migrate concrete Java classes to an SPI without breaking compatibility?

The best way to migrate concrete Java classes to an SPI without breaking compatibility is to introduce interfaces and factory methods. This refactoring approach enables safe API evolution by decoupling external consumers from internal implementations while maintaining modular boundaries.

Can I use Java records to define module boundaries for external consumers?

Yes, you can use Java records to define module boundaries for external consumers. Records provide a clean, immutable way to transfer data across API boundaries while interfaces handle behavioral contracts, together ensuring a minimal and stable public API surface.

How do I safely evolve a Java library API with minimal breaking changes?

Safely evolve a Java library API with minimal breaking changes by using factory methods, Service Provider Interfaces (SPIs), and modularization. These constructs allow you to update internal implementations and add features without altering the published public interface contracts.

Why does exposing concrete classes in a Java API hinder long-term evolution?

Exposing concrete classes in a Java API hinders long-term evolution because external consumers can directly access and depend on internal fields and implementations. This tight coupling forces breaking changes whenever internal logic must be updated or refactored.