-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remote Flutter Widgets (rfw) package feedback thread #90218
Comments
Hi, Ian, Very thrilled to see flutter team's effort on the dynamic UI ! We are evaluating on how to leverage rfw in our project. First of all, may I ask about the compatibility policy we will have in rfw ? In our project we will send down configuration data from server ( This is how we solve this: For each client release, we will snapshot the "capabilities" of the evaluator by the branch cut. The capabilities include
these snapshot capabilities data will be kept in our database, and keyed by the app release version. Before the configuration data is sent to client with version A, we will retrieve the capabilities data for version A, and go through all configuration data and validate that all configuration key/value are supported in the capabilities. Our feature is authored in a single place, but when releasing to different client versions we will do tree-shaking or branching and release different configuration data targeting different client apk versions. Could rfw package provide an interface that returns a structured data object that encodes all widgets / arguments its |
Right now there's no compatibility policy but there could be one. I think it makes sense to have a policy that we never break things. I don't know how easy it would be to accurately return what the supported API is. You can get the list of widgets easily enough by querying the map of constructors, but getting the arguments is non-trivial. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This package is not part of the flutter core repo, but a critical contribution to the flutter community. Flutter as a cross-platform app development framework lacks a go-to solution to let server dynamically control the runtime behavior. Even today there are quite a lot of solutions in the flutter community to tackle the same problem space, e,g https://github.com/Tencent/mxflutter. Many such solutions can benefit from this package if it can provide an official server payload specifications on widget constructions. #14330 (comment) |
@Hixie As suggested by you a few months ago, we are interested in cooperating rfw with flutter_rust_bridge. Could you please provide some suggestions on the details? Related: fzyzcjy/flutter_rust_bridge#296 |
(responded in the other issue — thanks!) |
@Hixie I only just came across this package yesterday and haven’t had a chance to kick the tires on it yet but I’m incredibly optimistic about this direction especially when it comes to app delivery and I am curious to hear your thoughts about what kinds of ways this could be extended and built upon in the future. One of the things I find hardest with Flutter web currently is just how much code I have to ship to get that first frame on the screen and the lack of modularity compared to say how I might deliver a regular HTML / JS / CSS based web app. It also gives me more control it seems over what kind of experience I want to render for what kind of user which I appreciate because again I feel like currently I’m in a position where I need to ship all possible set of experiences not only when the user might only want a tiny fraction of them but I have to do all of this before I even render a frame which is upsetting for everyone. I would love to see what a Flutter application server could look like. |
This technique doesn't reduce the amount of code you have to send down, really, since you still have to send the whole Flutter engine and the whole framework, but certainly something using this or another solution along this lines could give you more flexibility in terms of what the application does. |
Hi! Thanks for doing this for dynamic ui ! Are there any solutions for logic dynamic? Thanks a lot. |
Hi thanks for the package, I always wanted dynamic widget like you have in html, |
@hmbenhaim do you mean from an .rfwtxt file? |
Hey, I just wanted to add that I've found this package useful in designing a (sort of) interactive UI designer for my app. I hope it continues to be developed and maintained. |
Hi, I have a couple of questions and hope someone from the team can help; in general, this could be very useful, especially if you need to load custom widgets for enterprise customers, at least in our use case. My first question is whether there are plans to support this package, as I see there has not been a big use case. The second question would it be possible to load the following into a widget build method from, let's say Firestore
|
@isAlmogK Can you elaborate on what you mean by "support" exactly? For the second question, I'm not sure I understand exactly what you are asking; in general package:rfw does not allow imperative code to be sent from the server, only declarative widgets. You could send code as JavaScript or Wasm or some such though. If you have a clearer description of your use case I could try to advise in more detail. |
Just wanted to give this another try (had it working when it first came out but didn't have a usecase then, now I do), but currently I'm unable to run the example/wasm app, no matter the plattform I get an error that wasm could not be initialized, this happens in the build method of the example widget:
from what I see wasm was initialized correctly - I'm on a M1 mac.
|
Can you get the wasm package to work in isolation? |
-> looks like the hello_world example is running just fine
had to reinstall rust, but still no luck with rfw, did initialise wasm with |
I have no idea... does it work on a Linux box? On this Linux machine, modulo some other issue I'm having with LIBGL, if I just check out the rfw repo and go into the example/wasm directory and run |
Just hopped on my old Macbook with Intel processor and got the same error - the fact that the debug entitlements for network access are missing from
Currently I don't have access to another machine, but if it works on linux for you, thats good - that probably narrows this issue down to being mac specific (but not M1 mac specific) |
Aah, yes, it is probably that exact problem, indeed. |
I just created a small script to checkout and run the wasm example on a mac machine, to make this easier to test and reproduce: https://gist.github.com/dkbast/6af0c48eda59817b525798743f737918 # A shell script which sets everything up to run the rfw wasm example
# Setup Rust:
brew install rustup
rustup-init
source "$HOME/.cargo/env"
# clone the project
git clone https://github.com/flutter/packages.git
cd packages/packages/rfw
cd example/wasm
# Add internet access to the debug entitlements:
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>' > macos/Runner/DebugProfile.entitlements
# get dependencies
flutter pub get
# initialize wasm and build wasm runtime, this is why we need rust
flutter pub run wasm:setup
# build and run the wasm example
flutter run -d macos |
imagine I have some rfw text that creates button widget with text fetchec from DynamicContent I'd like to be able to track what sections of the rfw text map to the Button (or any widget). Also which keys in the DynamicContent are used by the widget. Think Chrome DevTools where you can hover over a DOM element and navigate to the HTML tag in the source view and vice versa. |
Can you file two bugs, one for each of these requests? We can look into what it would take to implement that. |
Filed #141658 to add support for widget builders. |
Filed #141665 to discuss wheter it makes sense to break the existing parser implementation into multiple subpackages to facilitate evolving the RFW language. |
Filed #141666 to discuss RFW ergonomics |
Filed #141668 to register even more local widgets in RFW. |
Filed #141669 to track adding more example apps to RFW. |
Filed #141670 to track migrating some tests to use dart testing utils (instead of flutter testing utils). |
Filed #141709 to notify developers about missmatching arguments. |
Filed #141948 to discuss/explore alternatives to |
@Hixie what happens if an RFW library imports two other libraries that contain a widget with the same name? Does the RFW compiler throw? One shadows the other? Do we have a mechanism to deal with that in place? Curious if you gave it a thought already. Also happy to file a new issue to discuss the language itself.
BTW I'm new to github so please let me know if I'm using gh issues the wrong way by using them as subthreads of this discussion. |
One shadows the other. There's a TODO somewhere about having enabling prefixes if it becomes a significant problem. |
Regarding my experience and improving the Dev Exp, this package uses a docs approach that is seen in many places and it unfortunately doesn't always help. E.G.: I'm trying to work with the core widgets and the syntax for doing so isn't clear. The examples given work fine, but when I start trying to add more parameters and other widgets, things break down. So I naturally go looking through the docs, in particular, createCoreWidgets( ) at https://pub.dev/documentation/rfw/latest/rfw/createCoreWidgets.html. There we find a list of widgets and English language descriptions of parameter syntax for exceptions to the norm. Since the English descriptions are not easy to visualize for someone who has never seen this package before, even if the person is a native English speaker like me, I clicked on some links for the widgets with the expectation I would find an RFW JSON example of how to implement each widget I clicked on. Instead, I found they're just links back to the standard widget catalog. This is not helpful, because anyone working with RFW's core widgets is already going to be more than a little familiar with the listed widgets such as Container, Text, and so on. We don't need a refresher on how the normal widgets work, we need to see how to make each widget work with RFW. As for the English language descriptions, here is the one for color: But what we actually need is: What prompted this reply is that I can't seem to make a TextStyle work no matter what I try. There is an English language entry in the docs for createCoreWidgets( ) that states, "For each, every parameter is implemented using the same name. Parameters that take structured types are represented using maps, with each named parameter of that type's default constructor represented by a key, with the following notable caveats and exceptions..." When I read that my gut reaction was, "What on earth does that mean?? I'm more confused now than before I read that..." TextStyle is not listed as an exception, so apparently I'm supposed to use a map in some way that I can't find an sample of in the examples "Hello" or Local (Remote and WASM don't contain JSON examples in their main.dart files.) Here is the example of Text from the Hello example: So far so good, until I try to use the same approach to change the color of the text: This causes an error not in the Text, but in the widget after the Text: "Expected symbol ":" but found ( at line..." Instead of just trying to find out about Text, I thought it better to go searching for a way to understand this whole approach because I'm sure there are dozens of other situations to which the same issue would apply. In short, the very first thing a user should see after the general description of any package are examples of exactly which syntax the developer has to type on the keyboard in order to use it that package in an app. We need that far more than English language descriptions, and for people who aren't trained formally as engineers the lack of this in so much documentation is a never ending source of blockers, frustration, and slow downs. I can't even begin to tell you how often I read all sorts of docs for different packages and think, "Okay, that's what it's doing at a high level but how do I make it do something in my code? What exact syntax do I need to type with my fingers in order to get this thing to work? One last point, this reminds me of when the core Flutter docs were so confusing because they were written by engineers on the team, for other engineers on the team, without much thought to whether or not the general public would be able to understand what they were reading. This is what was behind much of the effort to rewrite docs over the last few years. I wonder if the RFW contributors were writing these docs mainly for each other, rather than for the people who were coming to this cold, with no idea what any of it is about. EDIT: Gemini 1.5 FTW. It helps to have a million token context in which you can load half the source code. It found the TextStyle encoder/decoder. In case anyone else is having similar issues, here is the actual syntax: style: { So it appears to be a matter of omitting some of the constructors from time to time, in this case TextStyle. We just put the constructor's parameters in a map: parentClassParameterName: { I can't guarantee that's correct in all cases, but it's good for TextStyle. |
yeah, sorry for the poor quality documentation. there was a lot to document and i ran out of steam before getting to examples. |
I didn't find a way to show double or int variables passed into the widget with the Text widget, because it only supports String and disregards other types, but there is also no easy way to inline convert double/int to string, or is there? One solution would be to provide local widgets like DoubleText and IntText, and do necessary conversions there, but is there any other way of doing this? |
The simplest way is to have the data include both stringified and numeric versions. |
@Hixie is there any chance you could just make a one screen widget that includes uses of color, padding (AnimatedPadding, I know), gradient, and other such things? I'm just thinking you could make a "kids watercolor" where you throw in a bunch of junk that doesn't really go together, but just shows us what syntax to use for each thing that's not done the same way normal Flutter code is done. I'm so very close to having Gemini be able to build almost anything. I've got it working already, but I keep hitting blockers that are only because I can't give it examples of what syntax to use. It's able to use anything I've been able to feed it, but there are a lot of things I don't know about this syntax. I don't know a use case for Gemini controlling the screen remotely, and building it in whatever way the AI decides to, but you have to admit the idea is fascinating. Now I just have to figure out how to take it from parlor trick to something useful. |
Here is a sample widget showing how some parameters are used. I plan to update this as I keep learning more.
|
I want to contribute material widget -> Slider to the library but I don't have Linux machine to create and run the golden tests and they are skipped on mac and windows machines that I have, so my code coverage is not 100% without golden tests. What can I do? |
Join the Discord and beg someone to do it for you. :-) (link in the contributor docs) |
You can check my pull request for Slider widget |
A couple of points:
|
For use cases that generate text from LLMs, the recommended way to transmit the data to the client is to encode the generated text as the binary format on the server, and transmit that. That said, given the speed of LLMs today, the resulting performance improvement in likely insignificant. |
I have a question that I hope can be answered. Is it necessary for all code to be written within a single rfwtxt file? When dealing with complex UI nesting, I would prefer to encapsulate the code into different rfwtxt source files, rather than writing everything in one rfwtxt file. |
I'm a little confused by this because LLMs can only output text. I haven't been using a server, how would that work? And I agree, the performance choke point is always going to be the LLM. |
Made a RFW realtime editor! |
Nope, rfwtxt supports imports.
You would take the rfwtxt output from the LLM, encode it in the binary format, and send that. |
We are developers of Flutter Markup Language. and would like to discuss possibilities re: integration of RFW into FML. I can be reached via email at jeff@appdaddy.co or on discord @appdaddy. |
This issue is intended to collect feedback regarding the rfw package.
If you have found a bug with RFW, please file a new issue. This issue is specifically for discussing the package's general applicability to your use cases, to determine if this is a useful direction for us to follow, and to report experiences you may have with writing applications with this package. Thanks in advance.
The text was updated successfully, but these errors were encountered: