In the abstract, FastUI is like the opposite of GraphQL but with the same goal — GraphQL lets frontend developers extend an application without any new backend development; FastUI lets backend developers extend an application without any new frontend development.
I know a lot of backend developers who are backend developers specifically because they don't enjoy frontend work and prefer to leave that work to people who actually enjoy it. And I know a lot of frontend developers who feel the same way, only from the other side.
The tagline of FastUI is "Build Better UIs Faster," but I think this will likely end up being "Build Passable UIs Faster," because yes, for simple cases, you can represent HTML components as Python or Javascript or whatever other language you want, but once you need to build something complex on the frontend, it becomes very irritating very fast when you have to work like this -- and good luck getting your frontend buddies to help you, because now they have to get up to speed on a new framework to understand what it's doing.
Its a shame that RAD on the web is so far behind stuff like Qt
And Qt is leaps and bounds behind Delphi and Lazarus.
It is even behind rails g scaffold when it comes to RAD.
The ultimate RAD was Windows Forms, in my opinion. It's been downhill ever since.
Remember how you could just "add" a database connection to your project, plop a data source on a form, then a datagrid or a bunch of text/check/comboboxes and the standard control, wire it all up in a couple clicks, and things just magically worked?
That was a lovely time to work on any kind of line-of-business app.
Data source on the form idea originated from Borland Delphi. Later, Anders Hejlsberg quit Borland to work at Microsoft, where he implemented the idea of visual and non-visual components and property editors in .net
You would be even more impressed with Delphi, because after connecting your data source, your form fills with data at design-time. Lazarus and Typhon does the same.
THe ultimate RAD was Delphi.
You can do these in both Delphi and Lazarus, except with a much better GUI framework (comparing GUI only here, not everything you'd get with .NET). If anything having worked with Windows Forms for a while i think it was abandoned before it reached even what you could do in the midlate 90s in Delphi.
Layouts >> fixed size window
Web development used to have a RAD experience in the ages of PHP 4/ASP Classic and Dreamweaver.
For better or worse, we lost this capability in the path for code purity, RESTful services and SPAs.
and accessibility, and standards compliance, and maintainable code...
That’s why I said for better or worse :)
In a way I disagree with you.
On accessibility: I see more custom components that nobody cares to make it properly working with keyboard interaction compared to native HTML input components.
On standards - mixed feelings: we had XHTML, now we don’t. We had IE and jQuery to deal with it, now we don’t need it, but I still see many places that have the old “works best with” message, now with Chrome instead.
On maintainable code: it’s a different shit show, we exchanged spaghetti code for billions of npm dependencies that break if you dare to try and upgrade something.
Yeah you're not wrong, I'd stop half way around 2005, or maybe in the alternate world where the whatwg, Chrome etc never happened ;)
Actually, does Qt have something like FastUI? Been looking for one.
You can compile Qt to target the browser instead of native apps. But besides seeing a demo I don't know how good it is with performances, accessibility and so on.
I think Qt does have WASM compilation options, but I mean generating interfaces given models like Pydantic/Dataclasses/etc.
What makes Qt special here? Qt has its own issues that make it painful to use.
Interestingly, you could accomplish a similar thing with GraphQL if the frontend uses the type introspection GraphQL provides and the backend graphql schema implements HATEOAS-like principles to let the frontend become a UI that's agnostic to different backends. That might not be how most GraphQL implementations are used, but it's kind of a cool pattern.
The kind of site that gets all of their data stolen. It can be a cool pattern.
If serving up metadata about what the site already makes accessible via the API will get their data stolen, then the actual problem is they're not applying access controls to the data, not the introspection.
In Django I had code in every view ensuring that the user was not accessing another user's data. If I create an abstraction like a utility function or "model manager" to handle this, I have to remember to call it from every view. In Graphene, this logic would be in a resolver which is used across multiple views.
Rubbish
We didn't use GraphQL, but in my last company that was essentially what we did - every API call returned schema information about the parts of the model the current user had access to, with detailed type information and which validations to apply, and metadata that affected presentation, and the frontend built a UI from that.
We then let designers/frontend devs override that on a case by case basis instead of building from scratch, and where possible tried to roll that into the generic UI as components triggered by specific metadata from the backend. It was not entirely agnostic, but it was largely driven by metadata from the backend, so e.g. schema changes rarely needed much, if any, UI work unless they fundamentally changed how the page worked.
My approach to what they are doing in my last job was to augment our models with more fine-grained information than what the database schema held, as well as with metadata about which views made sense or were needed, and then output schema information in our API. The raw base case was generated directly from the live database schema, so even without a line of code you had something once you'd enabled it (default off for anyone but people with devops level admin rights because giving a default on view of a raw table is a recipe for leaking data), and most of what the models provided were just more structured forms of what the models already needed, such as validations.
Then we built a set of generic frontend components for that in React once.
And we then had an instant UI for 50+ models, but the frontend devs could trivially selectively override both the whole page for models where the default was too simplistic, or how to render specific types of fields or for specific fields of specific models.
The "instant UI" was flexible enough that for most "backend" views we never customised it on the frontend. But being able to have the frontend devs customise the user visible things was essential, and thanks to having the ability to replace things bit by bit they could focus on the things that didn't look or work right, instead of "everything". And a lot of their work then made it back into augmenting the backend with info to let the generic frontend apply those improved views elsewhere as well.
I have only had a cursory look at FastUI. If they do something similar to that, then great. If they actually try to have the backend generate all or most of the UI and serve that up instead of serving up metadata, then I fully agree with your issues.
So, how did the “override” work? What made it easier to replace a part not whole page without understanding how the framework worked?
Agree completely that is the only sane goal - just wondering how you got there?
"The framework" in this case was a very thin layer underneath a bunch of components for which one of the inputs was a prop that included the relevant part of the schema from the server. So at a top level you got everything. The default top-level component knew to look up a view definition, and type, and a function that knew how to render that type, and that was pretty much it.
Then it'd just apply that recursively. For a simple model there'd only be two levels: The view, containing a bunch of columns, and the columns themselves, and the view type knew to iterate over the columns in the view and look up their type and tell them to render themselves. For more complex views frontend devs might e.g. provide a custom view type that'd group columns based on certain attributes, but still delegate to the generic mechanism to render those columns.
So replacing a part just meant writing a component that knew how to render itself from its props, just like any other component. Just that some of those props would be coming from the backend.
We'd generally try to avoid replacing components if the only reason for a component was to override how something was rendered, and to focus on why it should be rendered differently and consider if we could reflect that 'why' in the data, or other ways.
E.g. were certain fields grouped together because they were semantically related? Then reflect that with an attribute in the "meta schema" for those columns, and make the frontend component render related groups according to the type of that group (let's say a bunch of fields reflects a user address). Incidentally this tended to be very simple, as with a relational model when there were groups like that the right thing was often for them to be a separate table/model anyway, and we 'just' needed to distinguish between type handlers for rendering an object 'as the page' vs. 'as a reference' vs. 'as a group within the page', and that was easy enough to distinguish "well enough".
At a top level, we'd look for a registered view-level component (or fall back on the default), within a view if the backend returned the model instance "in-line" we rendered it as a group, and if it returned an id, we'd render it as a reference.
So a "User" object for example would render as a profile view if it was not your user and you went to a page where the associated API call returned the User as the top level model, you personalised profile page w/optional edit view if it was your user, or a "pill" linking to the user profile if it was just a reference.
The idea was that frontend components should focus on how to render specific types of data in a specific context, rather than specifying how specifically to render the page, because it'd make no sense to have the frontend e.g. try to render a field that no longer exists, or try to render a field as a different type it is when the meta data about which fields were available and what type they are was already available.
That's the way I've been doing things for a long time as a freelancer also.
Especially for business oriented apps, most of the models only need a list view with a table, and a detail view displaying some properties and related lists of models.
It works wonderfully.
You would be surprised how far a company can get with a Django admin for customer service or sales teams.
Django admin is really extensible. I'm not seeing here how to offer multiple forms against the same model. Eg if a user can edit some of their profile but not the subscription plan field, while a sales team can.
https://github.com/pydantic/FastUI/blob/main/demo/forms.py#L...
This. In my experience frontend is not for everybody. There is a reason why FE and BE are often separated - because it makes sense in most non-trivial apps. Related, I never understood the appeal of isomorphic apps either. It's not like the code for UI and data access is very similar.
It looks to me like FastUI is literally the BFF pattern with a pre-supplied front-end. If that's true, then complaints about it should be viewed through the lens of who has control over the application, who is gaining control, and who is losing it.
I've had quite vocal arguments from front-end devs which, when we stripped back what they were actually complaining about, came down to the front end being in service of the back end, rather than vice versa as they were used to.
But, unlike frontend devs, designers and product managers believe these complex things are needed, they almost never are and actually bring a lot of issues with them instead. I rarely see a complex component/combination (in a SaaS, let alone on some landing/public page) and think, "well, that adds real value over just a standard component". If you can point some out, please do; there are very obvious cases where something else than standard is needed, but that also depends on your definition of standard; if I can buy complex off the shelve somewhere, you are not building something complex in the frontend and so you can use simple means to hook them up without the complexity.
A lot of custom front end components that I’ve built were more about aesthetics than functionality, so I agree that it’s often unnecessary. In terms of functionality, you can get really far using only native HTML elements.
One common front end component that you can’t build with vanilla HTML is an autocomplete/typeahead input. I’ve had to build a few of these in JavaScript and I do think they’re genuinely helpful. It’s helpful to get suggested options as you’re typing. I also think search results that get filtered in real time as you type are helpful and can’t be accomplished with pure HTML.
Yeah for this kind of simple UIs fast I might as well use something like Streamlit.
Edit - someone who has built with this has commented that they found things snappier than using Streamlit
https://news.ycombinator.com/item?id=39568486
I’m primarily a backend developer these days, because that’s just how it’s played out where I work. But we’ve made the choice to do most things with Typescript since it lets us share resources, libraries and cooperate better with code reuse/reviews and such. So I can fairly easily switch to working on our React frontend, what I can’t do, is to make quick frontends for the services which will sort of need an “excel” type frontend. We even have a fairly generic component for it, but it very rarely does the job because our business is… well demanding things they might not really need.
This looks like a good thing. In that regard. Maybe not for us, but definitely a very useful tool for all developers because it can potentially let you deliver business value rapid.
Which is what I read from the lines you quote. I see no backend vs frontend discussion here, I only see a useful tool.
Even if you want to eventually build it into your React frontend, a tool like this will offer immense value for internal testing by users who won’t be able to do it through something like Postman, which is basically 99% of the employees in non-tech enterprise.