DEV Community

FlutterJS
FlutterJS

Posted on

FlutterJS: I Built a Flutter Compiler That Outputs Real HTML (Not Canvas)

The Problem Nobody Talks About

Flutter Web has a secret: it's not really "the web."

When you build a Flutter Web app, everything renders to a <canvas> element. That's fine for complex apps, but for websites it creates serious problems:

  • No SEO – Google can't index canvas pixels
  • Huge bundles – 2-5 MB minimum, even for simple apps
  • Poor accessibility – No semantic HTML for screen readers
  • Slow first paint – 3-8 seconds to see content

I hit this wall when a client asked me to build a marketing site in Flutter. It looked great, but Google Search Console showed zero impressions. The site was invisible.

A Different Approach

What if Flutter compiled to actual HTML instead of canvas?

That's what I built. FlutterJS takes your normal Flutter/Dart code:

Scaffold(
  appBar: AppBar(title: Text('My Site')),
  body: Center(
    child: Text('Hello, World!'),
  ),
)
Enter fullscreen mode Exit fullscreen mode

And outputs semantic HTML:

<main>
  <header><h1>My Site</h1></header>
  <section>
    <p>Hello, World!</p>
  </section>
</main>
Enter fullscreen mode Exit fullscreen mode

Same Flutter DX. Real web output.

How It Works

  1. Write normal Flutter code – no special syntax
  2. Dart CLI analyzes your AST – full type resolution
  3. Generates JavaScript – with a lightweight VNode runtime
  4. Outputs semantic HTML – that search engines can index

The JavaScript runtime handles diffing and updates, similar to React's virtual DOM but optimized for Flutter's widget model.

The Results

Metric Flutter Web FlutterJS
Bundle Size 2-5 MB 50-100 KB
First Paint 3-8s <1s
SEO Score 0-30 90-100

What Works Today

Layout widgets:

  • Container, Row, Column, Center, Padding
  • Stack, Positioned, Expanded, Flexible, SizedBox

Material widgets:

  • Scaffold, AppBar, Drawer
  • ElevatedButton, TextButton, IconButton
  • TextField, Checkbox, Radio, Switch
  • Text, Icon, Image, Card

State management:

  • StatefulWidget, setState()
  • InheritedWidget
  • Navigation

What's Missing (For Now)

  • Package support – External pub.dev packages aren't fully supported yet. Pure UI code works great!
  • Animations
  • Advanced Material widgets (Tabs, Dialog, BottomSheet)
  • Cupertino widgets
  • CustomPainter

These are on the roadmap. The architecture supports them, I just haven't implemented them yet.

Try It

# Clone the repository
git clone --recursive https://github.com/flutterjsdev/flutterjs.git
cd flutterjs

# Activate the Dart CLI
dart pub global activate --source path .
dart pub get
dart run tool/init.dart

# Now you can use flutterjs commands
flutterjs --help
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 and inspect the page. You'll see real HTML elements.

Links

I Need Your Help

This is open source and I'm looking for contributors. If you care about Flutter on the web:

  • Test it and report bugs
  • Contribute missing widgets
  • Help with documentation

What widgets would you need for your use case? Let me know in the comments.

Top comments (0)