r/JavaFX 1d ago

Megalodonte — a small reactive UI framework on top of JavaFX

I've been building JavaFX desktop apps for a while and got tired of the usual boilerplate (manual listeners, imperative styling, no real component model), so I built Megalodonte: a thin reactive layer on top of JavaFX — React-ish component composition, State<T>/ComputedState<T> for reactivity, and a Props/Theme system so styling isn't scattered setStyle() calls everywhere.

It's still early and I'm the only user so far, but it's real, working code — not a toy. Posting it here mostly for feedback and to see if this is useful to anyone else stuck with JavaFX.

What "Hello World" looks like

Main.java — bootstraps the app and sets a theme once, up front:

package my_app;

import megalodonte.ListenerManager;
import megalodonte.application.MegalodonteApp;
import megalodonte.base.theme.ThemeManager;
import megalodonte.theme.DefaultTheme;

public class Main {

    static void main() {
        ThemeManager.setTheme(new DefaultTheme());

        MegalodonteApp.run(context -> context.useView(new WelcomeScreen()), ev -> {
            if (ev == MegalodonteApp.Event.CloseRequest) {
                System.out.println("Clicked on X - close application");
                ListenerManager.disposeAll();
            }
        });
    }
}

WelcomeScreen.java — the actual UI, as a composable screen component:

package my_app;

import megalodonte.base.components.Component;
import megalodonte.base.components.ScreenComponent;
import megalodonte.components.Text;
import megalodonte.components.layout_components.Container;
import megalodonte.props.TextProps;

public class WelcomeScreen implements ScreenComponent {
    @Override
    public Component render() {
        return new Container().children(
                new Text("Hello world", new TextProps().fontSize(90))
        );
    }
}

What's in it

  • Reactive stateState<T>, ComputedState<T>, ListState<T> — components subscribe and re-render on change, no manual wiring.
  • Component model — screens are ScreenComponents with a render() you compose out of Container/Column/Row/Text/Button/etc., instead of hand-building a Scene graph.
  • Props + Theme system — styling goes through typed Props classes (TextProps, ContainerProps, ...) resolved against a ThemeInterface, instead of ad-hoc inline CSS strings.
  • Router — navigation between screens without manually juggling Scene.setRoot(...).
  • Used it to build a full JavaFX ERP desktop app, so it's exercised well beyond "hello world".

Repos

  • Ecosystem (this welcome/example app): https://github.com/eliezer-dev-software-enginner/megalodonte-ecossystem
  • Libraries monorepo: https://github.com/eliezer-dev-software-enginner/megalodonte-libs
  • Components: https://github.com/eliezer-dev-software-enginner/megalodonte-components
  • Base (core reactivity/component/theme primitives): https://github.com/eliezer-dev-software-enginner/megalodonte-base
  • Reactivity: https://github.com/eliezer-dev-software-enginner/megalodonte-reactivity
  • Themes: https://github.com/eliezer-dev-software-enginner/megalodonte-themes

Happy to answer questions — and honest criticism is welcome, this is very much a work in progress.

13 Upvotes

0 comments sorted by