As simple as possible, but not simpler.

Codion Desktop
Application Framework

Type-Safe Domain Modeling

// Domain API
interface Country {
    EntityType TYPE = DOMAIN.entityType("world.country");
    
    Column<String> CODE = TYPE.stringColumn("code");
    Column<String> NAME = TYPE.stringColumn("name");
    Column<Integer> POPULATION = TYPE.integerColumn("population");
    Column<Integer> CAPITAL_ID = TYPE.integerColumn("capital_id");
    ForeignKey CAPITAL_FK = TYPE.foreignKey("capital_fk", CAPITAL_ID, City.ID);
}

// Domain Implementation  
EntityDefinition country() {
    return Country.TYPE.define(
        Country.CODE.define()
            .primaryKey()
            .maximumLength(3),
        Country.NAME.define()
            .column()
            .nullable(false)
            .maximumLength(52),
        Country.POPULATION.define()
            .column()
            .nullable(false),
        Country.CAPITAL_FK.define()
            .foreignKey()
            .caption("Capital"))
    .caption("Country")
    .build();
}

Declarative UI Building

// UI Component Creation & Layout
@Override
protected void initializeUI() {
    // Create typed components
    createTextField(Country.CODE)
        .columns(3)
        .upperCase(true);
    createTextField(Country.NAME);
    createTextField(Country.POPULATION);
    createComboBoxPanel(Country.CAPITAL_FK)
        .includeAddButton(true);

    setLayout(flexibleGridLayout(1, 4));

    // Layout with input panels
    addInputPanel(Country.CODE);
    addInputPanel(Country.NAME);
    addInputPanel(Country.POPULATION);
    addInputPanel(Country.CAPITAL_FK);
}

// Complete Application Bootstrap
EntityApplicationPanel.builder(WorldAppModel.class, WorldAppPanel.class)
    .domain(World.DOMAIN)
    .applicationName("World")
    .applicationVersion(WorldAppModel.VERSION)
    .defaultLookAndFeel(MonokaiPro.class)
    .defaultUser(User.parse("scott:tiger"))
    .start();

Reactive Models

public final class CandidateModel {
    
    private final FilterTableModel<CandidateRow, CandidateColumn> tableModel;

    private final State installedOnly;

    public CandidateModel() {
        tableModel = FilterTableModel.builder(new CandidateTableColumns())
            .supplier(new CandidateSupplier())
            .visible(new CandidateVisible())
            .build()

        installedOnly = State.builder()
            .listener(tableModel.items()::filter)
            .build()
    }

    public FilterTableModel<CandidateRow, CandidateColumn> tableModel() {
        return tableModel;
    }

    public State installedOnly() {
        return installedOnly;
    }
}

Reactive Components

public final class CandidatePanel extends JPanel {
    
    private final FilterTable<CandidateRow, CandidateColumn> table;
    
    private final JCheckBox installedOnly;

    private CandidatePanel(CandidateModel candidateModel, ObservableState installing) {        
        table = FilterTable.builder(candidateModel.tableModel(), createColumns())
            .sortable(false)
            .focusable(false)
            .enabled(installing.not())
            .cellRenderer(CandidateColumn.INSTALLED,
                FilterTableCellRenderer.builder(Integer.class)
                    .horizontalAlignment(CENTER)
                    .build())
            .build();

        installedOnly = checkBox(candidateModel.installedOnly())
            .text("Installed")
            .mnemonic('T')
            .focusable(false)
            .enabled(installing.not())
            .build();
    }
}

Why Codion?

🖥️ Desktop First

When web deployment isn't required, why accept web UI limitations? Codion delivers rich, responsive desktop interfaces without browser constraints, CSS complexity, or JavaScript fragility.

Modern Look & Feel Integration
Include 40+ professional themes in any Codion application via Flat Look & Feel integration. Users can switch between Material themes, developer favorites like Dracula and One Dark, or nature-inspired themes like Aurora Borealis and Sakura—all instantly, no restart required.

Native Desktop Advantages
• Keyboard navigation throughout with plenty of shortcuts
• System integration with file dialogs, clipboard, and desktop features
• True multitasking without browser tab limitations
• Memory efficiency without DOM overhead or JavaScript engines
• Offline capability with local data and no network dependencies

Professional UI Components
Rich tables, forms, and controls that scale to thousands of rows without performance degradation. Context menus, drag-and-drop, proper focus management, and accessibility features that work consistently across platforms.

Read the full desktop renaissance argument →

🔒 Type Safe

Every aspect of Codion is compile-time checked. No string-based column references, no runtime surprises. Foreign keys are first-class citizens with automatic loading and full IDE support.

// Compile-time safety everywhere
Entity country = connection.selectSingle(Country.CODE.equalTo("USA"));
String capitalName = country.get(Country.CAPITAL_FK).get(City.NAME);

// Query results are type-checked at compile time
List<String> artistNames = connection.select(Artist.NAME, Artist.ID.in(1, 2));

// Generic column definitions with type safety
Column<List<String>> TAGS = TYPE.column("tags", new TypeReference<>() {});
Column<Location> COORDINATES = TYPE.column("location", Location.class);

// Conditions enforce correct attribute types
Condition lowRated = Track.RATING.lessThanOrEqualTo(4);
Condition expensive = Track.UNITPRICE.greaterThan(BigDecimal.ONE);

🔄 Reactive by Design

Everything in Codion is observable. UI components automatically update when data changes. No manual synchronization, no event bus complexity. Just declare relationships and watch them work.

// Observable values with automatic change notifications
Value<String> filter = Value.builder()
    .nonNull("")
    .listener(this::onFilterChanged)
    .build();
State installedOnly = State.builder()
    .listener(this::onFilterChanged)
    .build();

// Components automatically bound to observable values
JTextField filterField = Components.stringField(filter)
    .hint("Filter...")
    .mnemonic('F')
    .lowerCase(true)
    .selectAllOnFocusGained(true)
    .transferFocusOnEnter(true)
    .enabled(installing.not())
    .build();
                        
JCheckBox installedOnlyBox = Components.checkBox(installedOnly)
    .text("Installed")
    .mnemonic('T')
    .focusable(false)
    .enabled(installing.not())
    .build();

Explore observable patterns →

🪶 Lightweight

Codion is built on Java Standard Edition only - Swing, JDBC, and RMI. No third-party application servers, no complex deployment scenarios, no framework bloat. Just clean, focused APIs that do exactly what they say.

📉 Reduces Complexity

Adding ONE detail table causes 61-109% code explosions in other frameworks. That's just basic CRUD - for business-grade features (sortable columns, keyboard navigation, export, validation indicators), other frameworks need 10-15x more code.

// Basic master-detail
React + Node.js:  515 lines
Spring Boot:      355 lines 
Codion:           143 lines (with enterprise features included)

// For feature parity with Codion's defaults:
React + Node.js:  ~1,915 lines (+1,400 for table features)
Spring Boot:      ~1,355 lines (+1,000 for UI features)
Codion:           143 lines (no additional code needed)

Read the full complexity analysis →

⚔️ Battle Tested

Codion has powered 50+ production applications over 20 years across scientific and government institutions, including critical infrastructure systems.

Explore the 20-year evolution philosophy →

🤖 AI/LLM Ready

Codion's parameterized builder APIs enable mechanical generation. Every method takes explicit parameters, making it perfect for AI-assisted development. It's accidentally 5GL-ready.

// LLM-friendly APIs
createTextField(Customer.NAME)
    .columns(20)
    .upperCase(true)
    .nullable(false);

Read about 5GL programming →

🏗️ Domain-Driven Design

Your business domain becomes executable, type-safe code. Define entities once with rich metadata, and Codion generates all CRUD operations, validations, and UI components automatically.

// Define business entities with relationships and constraints
interface Customer {
    EntityType TYPE = DOMAIN.entityType("store.customer");

    Column<String> EMAIL = TYPE.stringColumn("email");
    Column<String> PHONE = TYPE.stringColumn("phone");
    Column<Long> CREDIT_LIMIT = TYPE.longColumn("credit_limit");

    ForeignKey ADDRESS_FK = TYPE.foreignKey("address_fk", ADDRESS_ID, Address.ID);
}

// Business rules enforced throughout the application
Customer.EMAIL.define()
    .column()
    .nullable(false)
    .maximumLength(100)
    .searchable(true);

Explore domain modeling →

🚀 Rapid Development With Joy

No boilerplate hell, no configuration files, annotations or XML nightmares. From domain model to working CRUD application in hours. Clean APIs that work exactly as you'd expect, with full IDE support and compile-time safety.

// Domain definitions for a couple of tables ~100 lines
// Initial application and UI setup ~150 lines
// Run application and start testing