Apache Wicket × Oat UI

Wicket Oat

A modern, themeable component library for Apache Wicket — built on Oat's ultra-lightweight, semantic CSS and JS. No utility-class soup, no client framework, just Wicket the way you already write it.

Wicket 10.8+ Java 17+ Oat 0.8.1 MIT Licensed

Why Wicket Oat

Server-side components, modern look, zero JS framework

Wicket Oat wraps Oat's semantic HTML/CSS/JS in idiomatic Wicket Components and Behaviors, so you get a current, themeable UI without leaving Wicket's component model.

Fluent, dual API

Use Oat.Components for self-contained widgets, or apply Oat.Behaviors to any existing Wicket component — composition over inheritance, your choice per case.

Semantic & lightweight

Oat styles real HTML elements by default. ~10KB of CSS and JS total, no build step, no bundler, no utility-class soup in your markup.

Themeable

17 built-in themes, remembered per user in a cookie, plus your own themes registered in one line — full CSS custom-property theming to match your brand.

Just Wicket

Every component is an ordinary WebMarkupContainer, Panel, or Behavior subclass — test it with WicketTester like anything else in your app.

Accessible forms by default

Every form field automatically wires aria-describedby to its feedback message, toggles aria-invalid on validation errors and marks required fields — no extra markup or wiring required.

Forms the Wicket way

Fields take their model from a CompoundPropertyModel and their label from .properties, by id. Validation errors show inline, and feedback panels and toasts update themselves over Ajax.

Strict CSP out of the box

Works under Wicket's default nonce-based Content Security Policy: no inline scripts or styles, no 'unsafe-inline', no 'unsafe-eval'.

Get Started

Three steps to your first Oat component

1

Add the dependency

<dependency>
    <groupId>dev.jbaby</groupId>
    <artifactId>wicket-oat-core</artifactId>
    <version>0.1.1</version>
</dependency>
2

Install it in your application

public class MyWicketApplication extends WebApplication {
    @Override
    protected void init() {
        super.init();
        WicketOats.install(this); // adds Oat's CSS/JS; returns OatSettings for themes
    }
}
3

Build your first UI

add(Oat.Components.button("save", "Save changes", target ->
    Oat.toast(target, "Saved!", OatVariant.SUCCESS)));

add(Oat.Components.alert("notice", "Welcome back!", OatVariant.SUCCESS));
<a wicket:id="save"></a>
<div wicket:id="notice"></div>

Prefer plain Wicket constructors? Components like OatAlert, OatBadge, OatCard and the form fields work the same way with new — the factory is mainly there for components like OatButton that need a callback and would otherwise require subclassing:

add(new OatAlert("notice", "Welcome back!", OatVariant.SUCCESS));

Want the full walkthrough? See the Build a Contact Form tutorial.

The Application Frame

OatAppLayout: sidebar, topnav, and content — solved

Most business applications share the same shell: a collapsible sidebar for navigation, a top bar for identity and actions, and a content area in between. OatAppLayout is a WebPage base class that gives you exactly that, backed by Oat's data-sidebar-layout CSS grid — no layout CSS to write yourself.

Extend OatAppLayout (or the ready-made BasePage pattern shown here) and override a handful of hook methods. The sidebar collapses to an off-canvas panel under 768px automatically, toggled by the ☰ button — no extra JavaScript required, it's wired into Oat's vendored JS already.

public class BasePage extends OatAppLayout {

    @Override
    protected IModel<String> appNameModel() {
        return Model.of("My Business App");
    }

    @Override
    protected IModel<List<MenuItem>> sidebarMenuItemsModel() {
        return Model.ofList(List.of(
            MenuItem.of("Dashboard", DashboardPage.class),
            MenuItem.of("Customers", CustomersPage.class)
        ));
    }

    @Override
    protected Component createFooter(String id) {
        // Any component works here - the built-in switcher is one option
        return new OatThemeSwitcher(id);
    }
}

Pages then simply extend BasePage and add their own content — the sidebar, top bar, active-link highlighting, responsive behavior and the user's theme are already handled. Bookmarkable pages pass their PageParameters to super(...); menu items can carry parameters and translatable labels, and items for pages the user isn't authorized to open are left out.

My Business App
JD

Dashboard

Your page content renders here, inside <wicket:child/>.

Sample widget content…

Live demo — try the ☰ toggle, and resize your window.

Component Showcase

Everything below is real, live Oat markup

Not screenshots — this page loads the same Oat 0.8.1 build the library vendors, so what you see here is exactly what renders in your app.

General

Default Success Danger
OT
Saved. Your changes were applied.

Plan

Any HTML can live inside.

Navigation

What is Wicket Oat?

A themeable component library for Apache Wicket, built on Oat.

  • Overlays

    Delete item?

    This action cannot be undone.


    Manage your account here.

    Change your password here.

    Data Display

    NameStatus
    Invoice #1042Paid
    Invoice #1043Due

    Forms

    We'll never share it.
    Size
    Drop files or click to choose

    Feedback

    Your changes were saved.
    The server could not be reached.

    Theming

    17 built-in themes, plus your own

    Click a theme below to preview it live on this entire page — the same data-theme mechanism OatThemeSwitcher uses in your app, where the user's choice is remembered in a cookie (and works with any session class).

    // Switch the current user's theme (kept in a cookie)
    OatTheme.setCurrent(OatTheme.NORD);
    
    // In init(): the default theme, and your own themes defined in CSS
    WicketOats.install(this)
            .setDefaultTheme(OatTheme.LIGHT)   // or null to follow the browser
            .addTheme(new OatTheme("brand", "Brand", "🏷️"));
    
    // Pin one component to a theme, whatever the user chose
    card.add(Oat.Behaviors.theme(OatTheme.LIGHT));

    AI-Powered Development

    Give your AI coding agent a Wicket Oat cheat sheet

    Wicket Oat ships a standard Agent Skill — a plain SKILL.md plus a references/ folder — giving the agent deep knowledge of the Oat API, component library, and theming system. It works with any tool that supports this directory-based skill convention.

    1

    Grab the skill

    It lives in the repo at wicket-oat/ (SKILL.md + references/).

    2

    Point your agent at it

    Copy it into your agent's own skills folder — for example, with Claude Code:

    cp -r wicket-oat .claude/skills/wicket-oat

    Check your agent's own documentation for how it discovers or loads skills.

    3

    Just ask

    Once installed, try: “Add a primary Oat button that shows a success toast on click.” or “Turn this standard Wicket Label into an Oat success badge.”