rad 0.9.0 icon indicating copy to clipboard operation
rad: ^0.9.0 copied to clipboard

Platformweb

A zero-dependency frontend framework for writing web apps in plain Dart. Inspired from Flutter.

Rad #

Rad is a frontend framework for creating fast and interactive web apps using Dart. It's inspired from Flutter and shares same programming paradigm. It has all the best bits of Flutter(StatefulWidgets, Builders) and allows you to use web technologies(HTML and CSS) in your app.

Let's start #

Below is a hello world in Rad:

void main() {
  runApp(
    targetId: 'output',
    app: Text('hello world'),
  );
}

Let's see another example,

class HomePage extends StatelessWidget
{
  @override
  Widget build(BuildContext context) {
    return Text('hello world');
  }
}

void main() {
  runApp(
    targetId: 'output',
    app: HomePage(),
  );
}

If you're familiar with Flutter it don't even need an explanation. Internally, Rad has some differences that might not be apparent from the examples above so let's discuss them first.

Differences #

  1. First off, we don't use a rendering engine to render a widget or anything like that. Widgets are mapped to HTML tags and composed together the way you describe them.

  2. Second, you can use use CSS for adding animations without ever thinking about how browsers carries them out.

  3. Lastly, for layouts, you've to use HTML. And guess what? there are widgets for that.

    Let's take this HTML snippet:

     <span class="heading big">
       <strong>
         hellow
       </strong>
     </span>
    

    Here's how its equivalent will be written using widgets:

     Span(
       classAttribute: 'heading big',
       children: [
         Strong(innerText: 'hellow'),
       ],
     );
    

Flutter widgets #

Following widgets in Rad are inspired from Flutter:

  • InheritedWidget, StatelessWidget, StatefulWidget.
  • FutureBuilder, StreamBuilder and ValueListenableBuilder.

These widgets has same syntax as their Flutter's counterparts. Not just syntax, they also works exactly same as if they would in Flutter. Which means you don't have to learn anything new to be able to use them.

HTML widgets #

Let's take a look at another markup example:

<div>
  <p>Hey there!</p>
</div>

Here's how we'll write this using widgets:

Division(
  children: [
    Paragraph(innerText: 'Hey there!'),  
  ]
)

Although it's very descriptive but some people might find it bit more verbose so there's also an alternative syntax for HTML widgets:

div(
  children: [
    p(innerText: 'Hey there!'),
  ]
)

Apart from syntax/names, there are two very important characteristics of HTML widgets that we'd like to talk about:

1. HTML widgets are composable #

Just like other widgets, HTML widgets are composable and has same semantics in the sense that they can be composed and mixed together with other widgets. For example,

Span(
  child: ListView(
    children: [
      SomeStatefulWidget(),
      Span(),
      ...
    ]
  ),
);

In above example, a Span widget is containing a ListView widget. Further, that ListView is containing a StatefulWidget and a Span widget. The point we're trying to make is that HTML widgets won't restrict you to 'just HTML'. You can mix HTML widgets with other widgets.

2. HTML widgets are extendable #

Designing and re-using UIs is a common requirement of every project. HTML widgets are flexible enough that you can use them to create your own widgets and re-usable UIs. To give you an example, let's say you want a stack widget. First, create a StackEntry widget:

class StackEntry extends Division
{
  const StackEntry(Widget widget): super( 
    style: 'position: absolute; top: 0; left: 0;',
    children: [widget],
  );
}

Then create a Stack widget:

class Stack extends Division
{
  const Stack({required List<StackEntry> children}): super( 
    style: 'position: relative;',
    children: children,
  );
}

and that's pretty much it. Here's how you can use our newly created Stack widget:

  Stack(
    children: [
      StackEntry(Text('hellow 1')),
      StackEntry(Text('hellow 2')),
    ]
  )

This might not look like a big improvement at first but we've actually created a brand new widget that has its own identity and semantics using existing widget. Unlike other frameworks where you'd create a component by implementing bunch of methods, in Rad you can extend widgets to create new widgets.

Widgets Index #

Below is the list of available widgets in this framework. Some widgets are named after Flutter widgets because they either works exactly same or can be used to acheive same things but in a differnet way(more or less). All those widgets are tagged according to their similarity level. Please note that these taggings are based solely on my understanding of Flutter widgets/src. If you happen to find any big differences, do let me know.

Similarity tags:

  • exact: Exact syntax, similar semantics.
  • same: Exact syntax with few exceptions, similar semantics.
  • different: Different syntax, different semantics.
  • experimental: --

Abstract #

Builders #

Misc #

HTML Widgets #

Abbreviation , Anchor , Article , Blockquote , BreakLine , Button , Canvas , Caption , Code , Division , FieldSet , Footer , Form , Header , Heading(1-6) , HorizontalRule , IFrame , Idiomatic , Image , Input , InputCheckBox , InputFile , InputRadio , InputSubmit , InputText , Label , Legend , ListItem , Menu , Navigation , Option , Paragraph , Progress , Select , Small , Span , StrikeThrough , Strong , SubScript , SuperScript , Table , TableBody , TableColumn , TableColumnGroup , TableDataCell , TableFoot , TableHead , TableHeaderCell , TableRow , TextArea , UnOrderedList

FAQ #

Q. Can we use Rad for creating a dynamic website?

Yes, that's something this framework is good at.

Q. Can we use Rad for creating a single page application/or a web app?

Yes, that'll be perfect. Rad has widgets with powerful mechanics for dealing with nested routing, deep linking, history and state management.

Q. Is it SEO friendly?

Rad is a frontend framework and server side rendering is a must for better SEOs. Some frontend frameworks provides SSR but unfortunately we don't have that at the moment. However you can use a backend technology(PHP, Node, Erlang etc.) to stuff meta information in your root page, based on location that a client requested, before serving the page to client. We assure you that this is a sane, simple, and effective approach.

Q. Why Dart?

In-short: Peace of mind.

I actually tried writing this in TypeScript before. While we can do awesome things with types in TS, it also inherits craziness from JS (has to bind 'this', use arrow fun, and more things like that). Later I decided to give Dart a try and I quickly realized that Dart is a very underrated language. You don't have to trust me on that. I had wrote a lot of Dart code with Flutter, but the fact that I choosed TS at first place really shows how underrated Dart actually is. I deeply believe Dart is a amazing language, and I am thankful to all the people who helped create Dart and/or contributing to it, one way or the other.

Contributing #

For reporting bugs/queries, feel free to open issue. Read contributing guide for more.

18
likes
130
pub points
52%
popularity

Publisher

unverified uploader

A zero-dependency frontend framework for writing web apps in plain Dart. Inspired from Flutter.

Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

Icon for licenses.BSD-3-Clause (LICENSE)

Dependencies

meta

More

Packages that depend on rad