TeaVM compiles Java code to run in the browser, efficiently and quickly. It features short build times, small downloadable files, and a batteries-included toolset (including minification, tree-shaking, and packaging). Previous releases have conquered all similar open-source tools (that support threading) in independent testing: https://renato.athaydes.com/posts/comparing-jvm-alternatives...
I think Swing is a non-goal of this project. It provides good interop with the DOM and core JS methods, and it makes it easy to create your own interop for JS apis that aren't in the core.
If that's your goal, you should look at CheerpJ, which supports Swing and has the goal of making it so you can easily port applets and other existing apps to the web.
I think TeaVM is more focused on letting you share code with the web instead of porting entire apps.
+1 for for Codename One. It is the only tool I use when I need a mobile-only app. I have built numerous apps using Codename One, and have released 2 of them in app stores. Great Swing-like API, great examples, great documentation.
A little over 10 years ago, I ran across TeaVM for the first time (probably) on GitHub. We had been looking for a way to port Codename One to the web, but we needed thread support, which wasn't supported by any existing solutions.
I emailed Alexey (the creator of TeaVM) to ask if he had plans for thread support, and he replied that, while "proper" threads weren't possible, he had some ideas for supporting green threads. Over the following 6 months or so, Alexey would share updates on progress he had made on the thread front. In March 2015, he shared that he had found a new approach for async code that wouldn't affect the performance of single-threaded code, and would support natural stack traces.
We released a preview of our web port using TeaVM a month later, and it exceeded all of our expectations, both in how easy it ended up being to do the port (because of TeaVM), and on the performance.
Alexey's solution for supporting threads, was truly a piece of genius. Had he not created TeaVM, and added threading support, I don't think we would have ended up with our web port - or, at the very least it wouldn't have ended up performing nearly as well.
The in-browser H2 database is very cool, thanks for sharing. I'm a regular user of H2, but have only used it server-side so far.
How much trouble was it to get working? Not sure how doppio handles the absence of raw TCP connections and a standard filesystem in the browser, but if it works in doppio I would think it could work in TeaVM too.
I am more enthusiastic with Kotlin also compiling to wasm with Jetpack compose and now working in all major browsers. It provides a full modern UI framework and also compiles to mobile and desktop. Code is also usable on server and if using the JVM fully interoperable with Java.
Try calling Kotlin co-routines from Java, fully interoperable is it not.
Additionally I really dislike the anti-Java discourse in Kotlin circles, as if Kotlin was able to stand on its own, without the Java ecosystem, or Google's making it Java replacement on Android.
I didn’t get a sense of anti-java-ism from the parent poster. While I enjoy Kotlin more than Java I see the benefits of both, and from most folks I’ve spoken to about the two they seem fairly level-headed about the situation.
I think that for all language discussion online that there is a very small percentage of people that get over-inundated by the emotional feeling of “investing their time” into a language and wanting to not feel like they made a mistake or that their time was a waste.
I wish f# got the same treatment Kotlin did tooling wise, because if I were to compare the “interoperability” of the two with the incumbent on their respective VMs, my experience has shown that developing with Kotlin incurs much less friction on a day-to-day basis.
I have no doubt that part of that friction is due to the radically differing foundations that f# vs c# were built on, which as a positive for f# gives it some very cool features that Kotlin won’t have, but it leads one to ponder the RoI of diverging from the primary language.
I do agree with you that googles choice to adopt Kotlin for android rather than invest further into modernizing the jvm capabilities to allow for Java to be able to keep up better was definitely a boost to Kotlin, I assume they made that choice in a calculated manner. I also wonder if Kotlin would be seeing as much server side use at places like Google, was, Airbnb, etc if not for that move on googles part.
FWIW interoperability of F# with C# has improved substantially.
For example, compared to GP comment on coroutines - starting with version 6, F# natively supports writing asynchronous code with task CEs that are based on the same Task<T> type as async methods in C#. Asynchronous sequences (IAsyncEnumerable<T>) can be consumed with first-party FSharp.Control.TaskSeq package and work both ways too (ironically, it's what prompted me to look into F# in more detail, noticing how much terser working with them was compared to C#).
F# mainly lacks the kind of push Kotlin gets by being first-class on Android. But at the same time F# has excellent tooling support with Ionide and FSAC which can be consumed from VS Code, Neovim/Emacs and anything else that works with LSP, and there are two separate commerical offerings with first-class support - Rider and Visual Studio. It is also shipped out of box with .NET SDK including F# interactive for scripting which I find very productive.
If I were to employ it in my team for a task F# is particularly well-suited for, it would be a low-risk change that would not require other contributors to take any extra steps to work with it - it slots right into the same solutions and most F#-declared types can be consumed as is from C#. The adaptation effort required for experienced developers should be minimal too.
F# interop support has gotten way better. I have several f# services (suave, giraffe) in prod and agree that things have been only trending positive. I write rider fsharp most days, which is a pretty good experience compared to the old days of the mono fsgen tooling taking up 100% of cpu on macOS for no reason.
However, there are still some huge gaps that Kotlin doesn’t experience. Source-generation based tooling created a divide between c#/f# libraries (see ef.core.fsharp), mixed solutions have problems with aot, he’ll I spent 2 hours trying to get z3 to work with f# for an old advent of code problem before just writing it in typescript.
F# would be the language I would default to for 99% of things if the friction wasn’t ever present. I just somehow hit it on every project I use it on
I agree, source-generation is particularly unfortunate. I don't think it's a deal-breaker per se however - most of the time a small bindings project in C# is more than enough - I just accept it as a matter of life and get on with it, luckily it has not been particularly troublesome. Perhaps it's a bigger issue for people who would like to keep their projects C#-free (which is unfortunate, because C# is an awesome and productive language too).
The bigger issues for me personally is support for low-level primitives. Because F# has full HM type inference and of course gets to enjoy the same performance of struct generics as C# does - it is tempting to write HPC code for which C# can't infer the full generic signature the way F# and Rust can.
Unfortunately, however, in this specific area F# is outmatched because it has surprisingly less flexible pattern matching - list and array patterns in F# are bound to lists and arrays and you can't as easily match opaque objects, abstract classes or interfaces to a specific type with specific state inside, something that C# lets you do easily, where you can match, deconstruct, inline slice and unbox on any type that simply has the necessary "shape" without being bound to specific core types or interface implementations. You can work around most limitations with active patterns, but there is nothing that you can do that would give you `span is [var x, ..var rest]`.
Continuing the last point - C# has really pushed forward in making span-based and general performance-oriented code simple and idiomatic. In F#, the use of ref structs is much more restricted (please do not hold it against the team that works on it - it's a complex piece of functionality, just look at https://em-tg.github.io/csborrow/ as a start). As a result, F# is an extremely powerful and productive language that sits in an awkward spot where it is frustratingly close to being "the OCamlish Rust for .NET" thanks to its incredible type system, but at the same time if you do care about maximum performance with heavy data manipulation - you will be better served by C# still simply because it would take a lot of effort to make these specific areas in F# work just as well.
Important - these issues are _luxury_. Java ecosystem simply does not provide any alternatives due to limitations of the type system offered by JVM. So while indeed things could have been better, they do not have a proper alternative in Kotlin/Clojure/Scala at all, disqualifying them from certain performance domains completely.
On AOT - as long as you avoid printfn in F# and use string interpolation with Console.WriteLine and such you should be getting no AOT warnings. With library code it can be tricky, but it's usually caused by the abuse of un-analyzable reflection. You can always ping authors to perhaps take a look at it or use something better if available :) I'm enjoying AOC with F# and FSharpPacker too, but sadly don't have time to continue.
Agreed on c# having better low-level primitives available. I know Java has some long-term projects in flight (Valhalla and friends), but dotnet has all of that available today.
I’m curious in what industry you’re utilizing those features. I imagine you must be using mostly your own code since much of nuget contains things that don’t take performance as a first priority. I imagine it would be similar to the trading companies using Java where they toss out most of the standard library and most things on maven and create their own faster versions (which is also not dissimilar to gamedevs tossing out STL and making their own low-allocation libraries).
> I’m curious in what industry you’re utilizing those features.
Performance engineering for CDN systems!
> I imagine you must be using mostly your own code since much of nuget contains things that don’t take performance as a first priority.
This was my assumption too. While "much of nuget" trend continues to hold, there are actually quite a few performance-oritned libraries nowadays.
Bindings and binging generators (that are near-zero-cost), managed allocator implementations, high-performance parsers and serializers (which completely wipe the floor with alternatives written in flimsy languages like Go), higher-level APIs for graphics libraries (DX12, Vulkan, ...), high-performance primitive libraries, game engines, and more.
You are correct to point out that performance-sensitive code tends to avoid standard library containers and certain APIs, but CoreLib itself has been exposing quite a few APIs (like ArrayPool) and tends to practically always offer Span<T>-based method overloads so the data can reside in any memory if it needs so (stackalloc, array pool, unmanaged, or anything in between).
Sure, if you have a hot path you will probably avoid using List<T> and StringBuilder in favor of something less allocation-heavy, but it's generally the Unity land that is subjected to pain of fighting with every allocation rather than .NET itself.
While true the type system is a problem on the JVM world, that is taken care by the plethora of choice of implementations, some do include extensions.
Also while .NET is great and I favour it over Java when having the option, it is a guest on mobile OSes constrained by platforms FFI API surface, or subpar APIs (Catalyst on macOS), and Meadow isn't at the same level as PTC, Aicas, microEJ and many other embedded implementations.
TeaVM supports Kotlin as well. The difference with Kotlin/Wasm is that with Kotlin/Wasm you are limited only to Kotlin and can't use any code written in Java.
TeaVM author here. Personally I use it to bring a large (500KLOC) project that's written in Java and Kotlin to the browser (also we are using Graal VM Native Image to compile the same app to iOS, and Android supports). It's virtually impossible to maintain another 500KLOC code base on TS and on Swift and make sure that they behave and look 100% same. So the target audience is any team that wants to write in Java and/or Kotlin applications that works in JVM as well as in the browser.
JS frontend enthusiasts rationalized JS on the backend. Now Java backend enthusiasts can once again rationalize Java on the frontend.
I would consider this for a project where I already have Java code on the backend and rewriting it for the front end in JS is a bigger barrier than adding TeaVM to the stack.
* A developer or team has strong Java skills and wants to develop single-page apps
* A Java desktop project wants to move to the web and has lots of validation logic they don't want to double-maintain in Java and ECMAScript/WASM
* A Java-based game developer wants to make a Canvas-based version of their game for the web (potentially full-screen)
* A Java developer wants a batteries-included framework for web development. TeaVM comes with a minifier, tree-shaker, packager, and more, out of the box, with familiar 'mvn clean install' semantics (And Gradle support too).
* Grab A, some software that can be compiled to Java bytecode [1].
* Grab B, some software that can run wasm [2].
* Run A on B.
Just one example, since this "algorithm" can generate endless combinations! You could create some game logic in Kotlin, Clojure or Scala, compile it to WASM, and run it on Taca [3] (a runtime for multimedia wasm apps that runs native and in browsers).
--
1: from TeaVM front page: "the source code is not required to be Java, so TeaVM successfully compiles Kotlin and Scala"
2: There are many projects out there embedding some WASM runtime, not just browsers.
I'm sorry if this is a dumb question, I don't really know a lot about this field.
Would this allow me to play Puzzle Pirates (a Java game) in the browser, or would the developers still need to do some work for the game to be actually playable in the browser?
Would be cool if it had applet support. There used to be a very cool physics website, with all concepts explained using simulations running in Java Applets. Lost forever.
You could also check out https://jpro.one which is a commercial solution but very impressive - and because rendering is server side, very fast as long as you're in the same continent as the server. The website is itself served by JPro.
Of course you could also just distribute such apps as desktop apps... I will happily sell you a product that makes doing that easy :) https://hydraulic.dev/
We might have lost a decade since Unreal was running on Flash Crossbridge, yet thanks to Web trying to be a app platform to replace native apps, we are back full circle.
Java, .NET have their plugins back, even if with additional turtles along the stack, and stuff like Flutter are the new Flash.
I guess, thanks to all WebGL, WebGPU and WebAssembly folks
Java plugins were mainly useful to do naughty things (for instance in a previous life I used a Java plugin to load and call into a native DLL via JNI which spawned a Win32/D3D9 game client inside a browser by attaching as a child window of the Java plugin canvas). Fun stuff but not really a good idea from a security point of view ;)
And of course this cannot be replicated with a Java plugin running in a (browser) WASM engine.
To me, this is one of the many ingenious things about TeaVM's architecture. By using the preferred code execution mechanisms of browser vendors (WASM and ECMAScript, plus Web APIs) to deliver Java code, it ensures they can't block or shut down this delivery mechanism. They would have to cut off their noses to spite their faces.
Furthermore, since the browser vendors never want browser code to have public security issues, they work hard to find and fix problems in their sandboxes and runtimes. This of course benefits TeaVM apps as well, since they play in those same sandboxes, and gives them a level playing field with other web apps in perpetuity.
Plugin-based applets were only safe as long as Sun had clout and the browser vendors were investing less in security than the Java team.
True, WASM adoption is still low and could feasibly be removed, but TeaVM lets you target both JavaScript and WASM GC backends, so you are future proofed either way.
True, but are people turning off ECMAScript/WASM in their browsers to avoid this? As an app developer, I want to know if my app will keep running. In the Java Applet days, at some point the security scares became frequent enough to cause articles like "Turn off Java except on websites where you are actively using it". Once your users have to find and toggle a setting to make your app work, your audience size drops significantly.
I don't see such fears around ECMAScript/WASM. Since the dominant players have a vested interest in users feeling safe leaving those technologies turned on for all websites, they'll keep investing to maintain that safety (and the marketing of that safety).
This is a massive insurance policy for building a TeaVM app -- the foundational web technologies it builds on are receiving incredible investments from industry heavyweights. It's not just security that is maintained, new Web APIs are regularly developed too. Want to use USB from your web app? No need to wait for Oracle to roll out a Java API for it -- browser vendors have made a new API and you can call it from you TeaVM app right away.
TeaVM ( https://teavm.org/ ) is an Apache-licensed project, free for use in commercial projects. It is mature and used widely, including in frameworks like Flavour ( https://frequal.com/Flavour/book.html ) and more projects listed here: https://www.frequal.com/TeaVM/TeaVmBasedSites.html
TeaVM compiles Java code to run in the browser, efficiently and quickly. It features short build times, small downloadable files, and a batteries-included toolset (including minification, tree-shaking, and packaging). Previous releases have conquered all similar open-source tools (that support threading) in independent testing: https://renato.athaydes.com/posts/comparing-jvm-alternatives...