Tea web toolkit

109 views
Skip to first unread message

C B

unread,
May 24, 2025, 4:41:32 PMMay 24
to TeaVM
Im interested in creating a web toolkit (similar to GWT but modernized) based on TeaVM. The core features of this toolkit should be

1) ability to create components with the compiled javascript and associated css inside the final app bundle (no separate style sheet needs to be added to use the component)
2) an RPC mechanism
3) a template library similar to GWT's UIBinder.

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

Thanks. 

Alexey Andreev

unread,
May 24, 2025, 4:55:13 PMMay 24
to TeaVM
Im interested in creating a web toolkit (similar to GWT but modernized) based on TeaVM. The core features of this toolkit should be
Hi. Fortunately, you don't need to create it from scratch. You can borrow ideas or even fork my attempt to do such framework: https://github.com/konsoletyper/teavm-flavour
 
1) ability to create components with the compiled javascript and associated css inside the final app bundle (no separate style sheet needs to be added to use the component)
 
What is "a component"? And if you want to bundle CSS with a component, how would one re-use your components in their site with their own style/color theme/etc?

 
2) an RPC mechanism
RPC (or at least how it was implemented in GWT) is a bad idea. Everybody is using something like REST/JAX-RS or Swagger/OpenAPI. Or if you want RPC, then gRPC would be a solution. So it should be something standart, not GWT-style thing that is only limited to some particular framework.

 
3) a template library similar to GWT's UIBinder.

GWT's UIBinder is also a bad idea. Look how the same thing done in React, Angular, Vue or Svelte. Compared to them UIBinder is inapt to solve any practical task that occur as you want to write anything more complex than Hello, world.
 

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

 I'm afraid that reading an external file is out of compilation scope.You can try to use `Metaprogramming.getClassLoader` and read a resource, but with something "external" there's nothing ready-to-use, you have to invent it yourself. And what exactly do you mean by "I was not successful"?

C B

unread,
May 24, 2025, 5:34:10 PMMay 24
to TeaVM
On Saturday, May 24, 2025 at 3:55:13 PM UTC-5 konsol...@gmail.com wrote:
Im interested in creating a web toolkit (similar to GWT but modernized) based on TeaVM. The core features of this toolkit should be
Hi. Fortunately, you don't need to create it from scratch. You can borrow ideas or even fork my attempt to do such framework: https://github.com/konsoletyper/teavm-flavour
 
1) ability to create components with the compiled javascript and associated css inside the final app bundle (no separate style sheet needs to be added to use the component)
 
What is "a component"? And if you want to bundle CSS with a component, how would one re-use your components in their site with their own style/color theme/etc?


A component as in buttons, checkboxes, other controls, etc and more complex things like data tables, tab views, split views etc. To beable to create these, and ship the bytecode and css in a jar for re-use on as a maven dependency and no need to include an stylesheet in the host page.

 
 
2) an RPC mechanism
RPC (or at least how it was implemented in GWT) is a bad idea. Everybody is using something like REST/JAX-RS or Swagger/OpenAPI. Or if you want RPC, then gRPC would be a solution. So it should be something standart, not GWT-style thing that is only limited to some particular framework.

gRPC is a possibility. So is having a good client implementation of object mapper. But just REST and JSON  can be cumbersome and its use is more to serve as an generic API for arbitrary web/iOS/android clients.  Being able to make REST calls is always supported, but  RPC is a powerful mechanism when there is tight, monolithic shared client-server code. For example, I am implementing a page-layout editor, and want the ability to print the created document to PDF.  On the client, canvas is used. For Printing on the server, Java2d is used.  But the drawing code is the same Java code on both the client and the server. With RPC I just pass the Document object to the remote print method and it just works. No need to serialize to a JSON string, and ultimately if I did this would fundamentally be RPC and not REST. I think the term "REST" gets misused alot in the frontend industry.  
 
3) a template library similar to GWT's UIBinder.

GWT's UIBinder is also a bad idea. Look how the same thing done in React, Angular, Vue or Svelte. Compared to them UIBinder is inapt to solve any practical task that occur as you want to write anything more complex than Hello, world.

I disagree.  Its just a declarative XML, as are other UI format frameworks XAML and indeed html itself. I think youre referring to complaints that GWT is widget based and does not easily let you just use HTML/CSS. But there is no reason a UIBinder cannot be similar to how the javascript frameworks do it. The main thing is allows the "binding" of UI elements to objects. 
 

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

 I'm afraid that reading an external file is out of compilation scope.You can try to use `Metaprogramming.getClassLoader` and read a resource, but with something "external" there's nothing ready-to-use, you have to invent it yourself. And what exactly do you mean by "I was not successful"?

I was hoping that there was a way to tell the compiler to read a string called "cssString" from a file and then emit code like "injectStyle( cssString)" which creates a node in the HTML deader with the CSS. But I could not find a way to do this. I am willing to hire someone to help implement these, if people on this forum who have worked on the TeaVM compiler are interested. 

Alexey Andreev

unread,
May 25, 2025, 2:26:37 AMMay 25
to TeaVM

 

 
2) an RPC mechanism
RPC (or at least how it was implemented in GWT) is a bad idea. Everybody is using something like REST/JAX-RS or Swagger/OpenAPI. Or if you want RPC, then gRPC would be a solution. So it should be something standart, not GWT-style thing that is only limited to some particular framework.

gRPC is a possibility. So is having a good client implementation of object mapper. But just REST and JSON  can be cumbersome and its use is more to serve as an generic API for arbitrary web/iOS/android clients.  Being able to make REST calls is always supported, but  RPC is a powerful mechanism when there is tight, monolithic shared client-server code. For example, I am implementing a page-layout editor, and want the ability to print the created document to PDF.  On the client, canvas is used. For Printing on the server, Java2d is used.  But the drawing code is the same Java code on both the client and the server. With RPC I just pass the Document object to the remote print method and it just works. No need to serialize to a JSON string, and ultimately if I did this would fundamentally be RPC and not REST. I think the term "REST" gets misused alot in the frontend industry.  

With Swagger and JAX-RS you just call a method as well. So there's simply no need to create something non-standard.

 
 
3) a template library similar to GWT's UIBinder.

GWT's UIBinder is also a bad idea. Look how the same thing done in React, Angular, Vue or Svelte. Compared to them UIBinder is inapt to solve any practical task that occur as you want to write anything more complex than Hello, world.

I disagree.  Its just a declarative XML, as are other UI format frameworks XAML and indeed html itself. I think youre referring to complaints that GWT is widget based and does not easily let you just use HTML/CSS. But there is no reason a UIBinder cannot be similar to how the javascript frameworks do it. The main thing is allows the "binding" of UI elements to objects. 


No, UIBinder is only limited to binding properties of views to object's properties. As a developer I would expect that such tool can do something that a template engline would do, e.g. bind a list and make template engine repeat part of markup for every object in list, support conditions, etc.
 
 

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

 I'm afraid that reading an external file is out of compilation scope.You can try to use `Metaprogramming.getClassLoader` and read a resource, but with something "external" there's nothing ready-to-use, you have to invent it yourself. And what exactly do you mean by "I was not successful"?

I was hoping that there was a way to tell the compiler to read a string called "cssString" from a file and then emit code like "injectStyle( cssString)"

From which file?
 

I am willing to hire someone to help implement these, if people on this forum who have worked on the TeaVM compiler are interested. 
 
Nope, I'm not interested at all

Christopher Bruno

unread,
May 25, 2025, 5:07:23 AMMay 25
to Alexey Andreev, TeaVM


On Sunday, May 25, 2025, Alexey Andreev <konsol...@gmail.com> wrote:

 

 
2) an RPC mechanism
RPC (or at least how it was implemented in GWT) is a bad idea. Everybody is using something like REST/JAX-RS or Swagger/OpenAPI. Or if you want RPC, then gRPC would be a solution. So it should be something standart, not GWT-style thing that is only limited to some particular framework.

gRPC is a possibility. So is having a good client implementation of object mapper. But just REST and JSON  can be cumbersome and its use is more to serve as an generic API for arbitrary web/iOS/android clients.  Being able to make REST calls is always supported, but  RPC is a powerful mechanism when there is tight, monolithic shared client-server code. For example, I am implementing a page-layout editor, and want the ability to print the created document to PDF.  On the client, canvas is used. For Printing on the server, Java2d is used.  But the drawing code is the same Java code on both the client and the server. With RPC I just pass the Document object to the remote print method and it just works. No need to serialize to a JSON string, and ultimately if I did this would fundamentally be RPC and not REST. I think the term "REST" gets misused alot in the frontend industry.  

With Swagger and JAX-RS you just call a method as well. So there's simply no need to create something non-standard.

 
 
3) a template library similar to GWT's UIBinder.

GWT's UIBinder is also a bad idea. Look how the same thing done in React, Angular, Vue or Svelte. Compared to them UIBinder is inapt to solve any practical task that occur as you want to write anything more complex than Hello, world.

I disagree.  Its just a declarative XML, as are other UI format frameworks XAML and indeed html itself. I think youre referring to complaints that GWT is widget based and does not easily let you just use HTML/CSS. But there is no reason a UIBinder cannot be similar to how the javascript frameworks do it. The main thing is allows the "binding" of UI elements to objects. 


No, UIBinder is only limited to binding properties of views to object's properties. As a developer I would expect that such tool can do something that a template engline would do, e.g. bind a list and make template engine repeat part of markup for every object in list, support conditions, etc.
 
A template engine is not the same as XML tags representing objects. A UI component can be build from a template and then included in a broader user interface and represented with an XML tag and bound to an instance of the component.

The whole point is to abstract away HTML/CSS and write the application in a way similar to Swing/Cocoa/WPF.

If no higher order components and I am staying with just HTML/CSS, then yes I will just use a JavaScript framework and skip the unneeded headache of A TeaVM dependency. 

The framework you made seems like it’s Angular but you write in a JVM language. Seems like you are trying to increase the usage of Tea by catering to the army of front end devs. They will never love you.


 

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

 I'm afraid that reading an external file is out of compilation scope.You can try to use `Metaprogramming.getClassLoader` and read a resource, but with something "external" there's nothing ready-to-use, you have to invent it yourself. And what exactly do you mean by "I was not successful"?

I was hoping that there was a way to tell the compiler to read a string called "cssString" from a file and then emit code like "injectStyle( cssString)"

From which file? 

Any file in the project. 
 

I am willing to hire someone to help implement these, if people on this forum who have worked on the TeaVM compiler are interested. 
 
Nope, I'm not interested at all-- 

Well the offer was addressed to the forum, but now I realize you are the only one working on this . Impressive work for being a hobby project. Good luck.  

You received this message because you are subscribed to a topic in the Google Groups "TeaVM" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/teavm/Y8J87YBdrbY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to teavm+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/teavm/01556d7a-cef2-4fa4-bef0-7d22fcb2e129n%40googlegroups.com.


--
Chris Bruno
sent from my Mac Pro

C B

unread,
May 25, 2025, 3:58:41 PMMay 25
to TeaVM
I spent more time looking into Flavour today and actually I dont actually think we disagree on much. As I read through the flavour book, its basically what I was looking for. RPC is there with your services, and UIBinder is there with the templating system. I think you misunderstood that Im just looking to a straight port  of GWT. 
To unsubscribe from this group and all its topics, send an email to teavm+un...@googlegroups.com.

Steve Hannah

unread,
May 25, 2025, 4:32:01 PMMay 25
to C B, TeaVM
I think that the TeaVM ecosystem can benefit from a UI framework.  Alexey is focusing on the TeaVM core, so such a project needs to be led by someone else.

There is already a fork of flavour for another member of the community.  Perhaps you'll want to join that effort https://flavour.sourceforge.io/

I have experimented with TeaVM and WebComponents in the past and although my tinkering didn't lead to anything "useful", I still think there is a path forward in that direction.

We also use TeaVM as the basis for our JavaScript port in Codename One - so this also provides a UI component toolkit based on TeaVM, though this is a lightweight UI toolkit and it focused on mobile apps.  https://www.codenameone.com

SnapKit is another lightweight UI toolkit that uses TeaVM for it's web port.  It is also lightweight (like Codename One), but is focused desktop UIs.  It is really worth checking out, as there quite a few really nice "real" apps and demo apps. https://github.com/reportmill/SnapKit
(Some of the demos run using CheerpJ, and others with TeaVM - both are supported).

There are probably others, but these are the ones that I have played with myself.

Steve

--
You received this message because you are subscribed to the Google Groups "TeaVM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to teavm+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/teavm/0f2f7003-7351-4c32-8824-e5dddce29a55n%40googlegroups.com.


--
Steve Hannah
Web Lite Solutions Corp.

C B

unread,
May 25, 2025, 5:30:24 PMMay 25
to TeaVM
Thanks Steve, I will check out the projects you sent. 

I became interested in TeaVM because I started using Kotlin and really love the language,  and obviously GWT does not support Kotlin. I checked into Kotlin/JS but it seems to have fallen out of focus at JetBrains and even when it was supported the focus was using things like webpack and leveraging the existing Javascript ecosystem.  For me it doesn't make sense to use Java/Kotlin if Im ultimately using javascript tools and frameworks. Instead I want a break from this ecosystem, an alternative. 

The problem is there are few alternatives. GWT development is in stasis.  There is Vaadin and Blazor but those have their own issues.  Upon finding TeaVM I thought the ideal would be TeaVM with the tooling of GWT, but modernized and improved. Not just using nodejs tools and javascript frameworks from another language. A real alternative. 

Alexey Andreev

unread,
May 26, 2025, 3:54:15 AMMay 26
to Christopher Bruno, TeaVM


 

I looked into  using TeaVM meta programming to implement 1): I was trying to read a css file a compile time and inject the string into the emitted javascript. But I was not successful. For the above features, having the compiler read files and do something with the contents is necessary. Can someone on this forum offer me guidance? 

 I'm afraid that reading an external file is out of compilation scope.You can try to use `Metaprogramming.getClassLoader` and read a resource, but with something "external" there's nothing ready-to-use, you have to invent it yourself. And what exactly do you mean by "I was not successful"?

I was hoping that there was a way to tell the compiler to read a string called "cssString" from a file and then emit code like "injectStyle( cssString)"

From which file? 

Any file in the project.


Which file? Can you define exactly what you mean by 'read a string called "cssString" from a file'? What file you are going to use, how are you going encode a string, how are you going to extract a string, what is 'a string' in the first place?


Christopher Bruno

unread,
May 26, 2025, 7:22:38 AMMay 26
to Alexey Andreev, TeaVM
I was trying to load a CSS file the same way its done in vite or gwt, where if you have a component, say Button.kt, the styling CSS file is in the same directory, a file called style.css . The string is the contents of style.css which I would inject via a dom manipulation in the header of the host page on document load. 

Alexey Andreev

unread,
May 26, 2025, 7:33:31 AMMay 26
to Christopher Bruno, TeaVM

> I was trying to load a CSS file the same way its done in vite or gwt,
> where if you have a component, say Button.kt, the styling CSS file is
> in the same directory, a file called style.css . The string is the
> contents of style.css which I would inject via a dom manipulation in
> the header of the host page on document load.

So what you need to do is to somehow put style.css into jar file. Unlike
GWT, TeaVM does not read sources, it expects your compiler to read files
and your build system to produce jar file, then it takes this jar file
and turns it into JS. So you should play with your build system (either
Gradle or Maven) to make them package CSS files into jar. Then you can
use `Metaprogramming.getClassLoader` to read these CSS files from jar file.

Nikola

unread,
May 26, 2025, 7:52:20 AMMay 26
to TeaVM
I have also built a custom template system inspired by Vue, React, and Angular.
HTML markup, CSS, and Java code are combined into a single Java file, acting as a component.
You can check it out here: https://github.com/dncomponents/dncomponents-tea/blob/main/main-reactive/README.md
We're using it in production in our project, although it still needs further development for improved stability.
Even in its current state, It could potentially serve as a useful concept or idea

Alexey Andreev

unread,
May 26, 2025, 8:29:56 AMMay 26
to te...@googlegroups.com

> I have also built a custom template system inspired by Vue, React, and
> Angular.
> HTML markup, CSS, and Java code are combined into a single Java file,
> acting as a component.
> You can check it out here:
> https://github.com/dncomponents/dncomponents-tea/blob/main/main-reactive/README.md
> We're using it in production in our project, although it still needs
> further development for improved stability.
> Even in its current state, It could potentially serve as a useful
> concept or idea

I see one problem here: you should specify everything as a Java string,
which:

1. Is inconvenient, since Java (unlike Kotlin) still does not support
multiline string literals

2. Won't benefit from IDE assistance, unless you write a plugin for each
IDE that allows to recognize specific strings as embeddings in other
languages.


Also, I still don't understand the whole idea with keeping CSS right
with component code. Imagine I write a component which Alice and Bob
want to use in their web applications, each having own style. In case of
CSS file coming right with component itself they are tied to the style I
supplied with my component, right? In case I don't have any pre-existing
CSS, it's easy: they just take my component and write CSS that matches
styles of their apps.

Nikola

unread,
May 26, 2025, 10:29:15 AMMay 26
to TeaVM

1)
Java supports string literals known as text blocks since Java 13.
It's also possible to have an HTML file with the same name as the Java class and place the HTML markup there — for example, HelloComponent.java and HelloComponent.html.

2)
In IntelliJ IDEs, you can specify the language of a string using a comment like // language=HTML. The IDE will then recognize and highlight the syntax.
Also you can right-click on the string and select 'Inject Language or Reference' from the context menu to choose the language manually
e.g

//language=html
@Component(template = """
       <div class='helloCss'>
         <h1>Hello, {{name}}!</h1>        
       </div>
         """,
//language=css
       css = """
               .helloCss{
                          background: lightgreen;
                          padding: 20px;
                          border: 1px solid gray;
                        }
                 """,
       tag = "HelloComponent"
)

public class HelloComponent implements IsElement {
   HtmlBinder<HelloComponent> binder = HtmlBinder.create(HelloComponent.class, this);

   String name = "All";

   public HelloComponent() {
       binder.bindAndUpdateUi();
   }

   @Override
   public HTMLElement asElement() {
       return binder.getRoot();
   }
}

3)
Good question. In my case, although CSS is written alongside the component code, it doesn't stay isolated per component at runtime. Instead, all the CSS is extracted into a single CSS file that's included in the final build.
Because of that it's still easy to customize them just like with regular CSS

Alexey Andreev

unread,
May 26, 2025, 12:12:30 PMMay 26
to Nikola, TeaVM

> 1)
> Java supports string literals known as text blocks since Java 13.
It's
> also possible to have an HTML file with the same name as the Java
> class and place the HTML markup there — for example,
> HelloComponent.java and HelloComponent.html.
Ah, sure. I confused with string interpolation, that was experimental
somewhere in Java 22-23 and then was revoked.
>
> 2)
> In IntelliJ IDEs, you can specify the language of a string using a
> comment like // language=HTML. The IDE will then recognize and
> highlight the syntax.
> Also you can right-click on the string and select 'Inject Language or
> Reference' from the context menu to choose the language manually
> e.g

Cool, did not know. Also, it was even better if I could apply such
annotation comments to definition of annotation fields, so that user
would never put such comments at annotation use site manually.


C B

unread,
May 28, 2025, 6:50:18 PMMay 28
to TeaVM
On Monday, May 26, 2025 at 7:29:56 AM UTC-5 konsol...@gmail.com wrote:

 
Also, I still don't understand the whole idea with keeping CSS right
with component code. Imagine I write a component which Alice and Bob
want to use in their web applications, each having own style. In case of
CSS file coming right with component itself they are tied to the style I
supplied with my component, right? In case I don't have any pre-existing
CSS, it's easy: they just take my component and write CSS that matches
styles of their apps.


The reason is sometimes the functionality of a UI component relies on CSS: for example a slider component will have a track of a certain height/width and a thumb positioned relative to the tract with a certain height width. Or an accordion view might have an arrow indicator that animates 180 degrees when toggled, requiring a transform in the CSS. Yes the user can supply these but then they are participating in the writing of the component.   You could supply them an entire style.css for your UI library, but what if they only use a few components?  Then you only want to inject the css used, not the entire style sheet. They can always override the styles by providing their own stylesheet. For me its more of an elegance of using the compiler to produce the smallest bundle possible.

Steve Hannah

unread,
May 28, 2025, 7:51:30 PMMay 28
to C B, TeaVM
Web components "shadow dom" also works this way, allowing you to define css for your component's shadow dom that is not affected by the page CSS.  You bundle the css, similarly with the component, exposing only the parts that you want to expose for customized styling.



Steve Hannah
Web Lite Solutions Corp.

--
You received this message because you are subscribed to the Google Groups "TeaVM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to teavm+un...@googlegroups.com.

ScraM Team

unread,
Jun 12, 2025, 12:14:20 AMJun 12
to Steve Hannah, C B, TeaVM
Just want to add that Flavour is alive and well.  I have built numerous personal and commercial projects using it, and I think it's the best option out there for JVM web development.  I just made a new release (0.3.1) this week, it's already live on Maven Central.  0.3.2 is already planned and will incorporate new patches submitted from the community.

Flavour home page: https://flavour.sf.net/

Flavour is built on TeaVM and wouldn't exist without Alexey (konsoletyper).  Please support him on Github, I do.

Kerby Martino

unread,
Jul 5, 2025, 9:32:44 AMJul 5
to TeaVM

Hi ScraM,

How production-ready is your version of Flavour? Alexey mentioned that Flavour may not officially exist anymore, and I agree with his point about using SVN instead of Git — it is a bit unusual. I actually tried to create a GitHub mirror but wasn't successful.

Additionally, I noticed it's still using Java 8 and an older version of TeaVM. Is there a particular reason it hasn’t been updated to the latest TeaVM?

P.S. I'm genuinely interested in using Flavour for real projects, but I'm cautious about the risk of it breaking during development. Have any specific projects been successfully built with Flavour? What were the biggest challenges encountered?

ScraM Team

unread,
Jul 5, 2025, 7:55:34 PMJul 5
to TeaVM
I have used Flavour on about a dozen commercial and personal projects.  Fee free to try some of these public ones to see just how stable and performant it is:
  • Wordii: A 5-letter word game with no waiting
  • CalorieFreq: A calorie and exercise tracker: https://frequal.com/cf/
  • Tea Sampler Part demo, part tutorial, Tea Sampler shows how to use several key features of a Flavour application.

Flavour is alive and well, with 2 releases in the several weeks and another coming soon.

Java 17 support is officially coming in the 2.0 version, which is in final testing.  All fo the changes are already checked in on the 2.0 branch, please try it and see how it works for you.

It is one of the most stable UI development environments I've ever used.  There has been only one breaking change (minor) in the 8+ years I've been developing apps using Flavour.  No breaking changes are planned for the foreseeable future.  

Thanks!

Kerby

unread,
Jul 30, 2025, 3:19:58 PMJul 30
to TeaVM
Hi Andrew/ScraM,

Area you open for an online call about Flavour? 
Reply all
Reply to author
Forward
0 new messages