OpenMetadata Coding Standards: Complete Guide to Java, TypeScript, and Python Guidelines

OpenMetadata enforces strict, cross-language coding standards documented in CLAUDE.md and enforced automatically via CI pipelines to ensure production-ready, maintainable code.

The OpenMetadata project maintains a unified codebase spanning Java backend services, TypeScript/React front-end applications, and Python ingestion connectors. This guide breaks down the project's coding standards as defined in CLAUDE.md and DEVELOPER.md, with practical examples from the source code.


General Coding Principles

All contributors must follow these foundational rules across every language:

  • No unnecessary comments — write self-documenting code with clear naming
  • Every change must pass CI lint and format checks before merge
  • Follow language-specific standards detailed in the sections below

These rules appear in CLAUDE.md – Comments Policy and are enforced in .github/workflows/** pipelines.


Java Coding Standards

The OpenMetadata backend in openmetadata-service/src/main/java/** follows strict Java 21 conventions defined in CLAUDE.md – Java Code Requirements.

Formatting and CI Enforcement

Run mvn spotless:apply after every Java change. The CI pipeline fails if code is unformatted.

Method Structure Rules

Metric Limit Rationale
Method length ≤ 15 lines Single responsibility
Nesting levels ≤ 3 Readable control flow
Cyclomatic complexity ≤ 10 Testable paths
Parameters ≤ 5 Use parameter objects

Import and Modifiers

  • No wildcard imports — import only required classes
  • Use final for immutable local variables
  • Make defensive copies for collections passed to constructors

Modern Java 21 Features

Prefer pattern matching, switch expressions, List.of(), and correct Optional usage. Avoid magic strings — use constants or enums.

Java Example: Clean Method Structure

// ✅ Good: short, single-purpose, early-return style
public void deleteEntity(UUID id) {
    Entity entity = getEntity(id);
    if (entity == null) {
        throw new EntityNotFoundException(id);
    }
    if (!entity.isDeletable()) {
        throw new IllegalArgumentException("Entity cannot be deleted");
    }
    repository.delete(entity);
}

This method from openmetadata-service demonstrates the 15-line limit, early returns, and clear naming that CLAUDE.md requires.


TypeScript and Front-End Coding Standards

The React application in openmetadata-ui/src/main/resources/ui/** follows strict TypeScript rules documented in CLAUDE.md – TypeScript/Frontend Code Requirements.

Type Safety

  • Never use any — use proper types or unknown with type guards
  • The ESLint no-unsafe-any rule catches violations

Import Organization

Follow strict import ordering:

  1. External libraries
  2. Internal absolute imports
  3. Relative imports
  4. Assets

Run yarn organize-imports:cli before committing.

ESLint Rules

Rule Requirement
No console.log in production Remove or use proper logging
Strict equality === over ==
Line length Maximum 200 characters
JSX Self-closing tags, alphabetic props

Formatting

Run yarn prettier before every commit.

Internationalization

All UI strings must use useTranslation with keys from locale JSON files. Run yarn i18n to sync keys across all locales. Keys use kebab-case.

TypeScript Example: Proper Typing and i18n

import type { Table } from 'generated/api/v1/table';
import type { RJSFSchema } from '@rjsf/utils';

const TableCard: React.FC<{ table: Table }> = ({ table }) => {
  const { t } = useTranslation();
  return (
    <Card title={t('label.table')}>
      <pre>{JSON.stringify(table, null, 2)}</pre>
    </Card>
  );
};

This component from openmetadata-ui demonstrates no any, proper import ordering, and useTranslation for the 'label.table' key.


Python Ingestion Coding Standards

The ingestion framework in ingestion/src/metadata/** follows pytest-based standards in CLAUDE.md – Python Code Requirements.

Testing Framework

  • Use pytest exclusively — no unittest
  • Use plain assert statements, not self.assertEqual()
  • Replace setUp/tearDown with pytest fixtures

Test Design

  • Mock external services only — prefer integration tests for real behavior
  • Every bug fix must add a failing test first

Connector Organization

Keep connector-specific logic in its own directory. Never place connector code in shared helper files like builders.py.

Formatting

Run make lint and make py_format before committing. These enforce Pylint, Black, and isort rules.

Python Example: Proper Connector Placement and pytest


# ingestion/src/metadata/ingestion/source/database/postgres/connection.py

class PostgresConnection(BaseSQLConnection):
    def get_service_connection(self) -> PostgresConnectionConfig:
        # Connector-specific logic lives here

        return self.config

def test_postgres_connection_success():
    conn = PostgresConnection(config=valid_cfg)
    assert conn.test_connection() is True

This follows the rule that PostgresConnection stays in postgres/ rather than leaking into shared builders.py.


UI Styling Standards

The design system in openmetadata-ui uses Tailwind with strict conventions from CLAUDE.md – Styling.

Component Library

Use openmetadata-ui-core-components — never add MUI (Material-UI) directly.

Tailwind Configuration

  • Use tw: prefix for all Tailwind classes
  • Reference CSS tokens from globals.css — no hard-coded colors or spacing

Custom CSS

  • Use BEM naming for custom CSS
  • No .less files for new styles

Styling Example: Tailwind with Prefix

<div className="tw:flex tw:items-center tw:justify-between tw:bg-primary-500 tw:p-4">
  <Button>{t('label.run')}</Button>
</div>

Using tw:flex instead of flex ensures compatibility with the project's style linting.


Testing Standards

Quality gates in .github/workflows/** enforce comprehensive testing rules from CLAUDE.md – Testing.

Coverage Requirements

  • 90% line coverage on changed code
  • Missing coverage blocks merge

Asynchronous Testing

  • No Thread.sleep() — use Awaitility (Java) or Playwright's web-first assertions

Playwright E2E Rules

Avoid anti-patterns:

  • No waitForLoadState('networkidle')
  • No page.pause()
  • No .only in committed tests

Regression Testing

Every bug fix must include a failing test that proves the bug, then passes with the fix.


Documentation Standards

Public APIs and UI text follow strict documentation rules in [CLAUDE.md](https://github.com/open-metadata/OpenMetadata/blob/main/CLAUDE.md).

API Documentation

All public Java and TypeScript APIs require JavaDoc or TypeScript doc comments.

Internationalization

  • All UI strings via useTranslation hook
  • Locale keys in kebab-case
  • Sync across all locale files with yarn i18n

Key Configuration Files

File Purpose
[CLAUDE.md](https://github.com/open-metadata/OpenMetadata/blob/main/CLAUDE.md) Central coding standards for all languages
[DEVELOPER.md](https://github.com/open-metadata/OpenMetadata/blob/main/DEVELOPER.md) Workflow guidance and tooling commands
.github/workflows/** CI pipelines enforcing all standards
openmetadata-service/src/main/java/** Java backend implementation
openmetadata-ui/src/main/resources/ui/** React/TypeScript frontend
ingestion/src/metadata/** Python ingestion framework

Summary

OpenMetadata coding standards create a maintainable, production-ready codebase through:

  • Automated enforcement — CI pipelines run mvn spotless:apply, yarn prettier, make lint, and coverage gates
  • Strict language rules — Java 15-line methods, TypeScript no-any, Python pytest patterns
  • Architectural boundaries — connector-specific logic isolated, shared components in openmetadata-ui-core-components
  • Quality gates — 90% coverage, no Thread.sleep(), every bug fix proven with a test

Contributors should bookmark [CLAUDE.md](https://github.com/open-metadata/OpenMetadata/blob/main/CLAUDE.md) as the single source of truth and run the documented formatter commands before every commit.


Frequently Asked Questions

What is the maximum allowed method length in OpenMetadata's Java code?

Methods must be 15 lines or fewer. This rule in CLAUDE.md enforces single-responsibility methods. The CI fails builds where mvn spotless:apply cannot automatically fix violations.

How do I format TypeScript code before committing?

Run yarn organize-imports:cli followed by yarn prettier. These commands enforce import ordering, eliminate any types, and apply the 200-character line limit. The CI rejects unformatted TypeScript changes.

Where should I place Python connector-specific logic?

Always in the connector's own directory under ingestion/src/metadata/ingestion/source/. Never place connector logic in shared helpers like builders.py. This boundary prevents tight coupling and ensures clean architecture.

What test coverage is required for code changes?

90% line coverage on all changed code. The CI pipeline calculates coverage and blocks merges below this threshold. Additionally, every bug fix must include a failing test that passes with the fix applied.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →