// build native apps with SolidJS and Flutter

Signals in.
Pixels out.

TYPESCRIPTApp.tsx14 ln
import { createSignal } from "solid-js";

export default function App() {
  const [count, setCount] = createSignal(0);

  return (
    <view flex={{ align: "center", justify: "center", expand: true }}>
      <text fontSize={48} fontWeight="bold">
        {count()}
      </text>
      <gestureDetector onTap={() => setCount(c => c + 1)} />
    </view>
  );
}
DARTmain.dart15 ln
import 'package:flutter/material.dart';
import 'package:solid_fuse/solid_fuse.dart';
import '_generated/fuse_packages.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final runtime = await FuseRuntime.create();
  registerFusePackages(runtime);
  await runtime.start();

  runApp(MaterialApp(
    home: FuseView(runtime: runtime),
  ));
}

Fuse is a framework for building native apps with SolidJS and Flutter. Reactive signals drive real widgets through an embedded JS engine. No webview, no bridge serialization, no compromise. Write TSX, render with Impeller, ship to all platforms.

01 — features

Why Solid Fuse

The best parts of two ecosystems, connected at the rendering layer.

Fine-grained reactivity

Signals propagate directly to widget props. No VDOM, no diffing. A signal changes, one widget rebuilds.

const [count, setCount] = createSignal(0);

// signal changes → one widget rebuilds
<text fontSize={48}>{count()}</text>
<gestureDetector onTap={() => setCount(c => c + 1)} />

Native performance

Impeller GPU rendering. Rust-powered JS runtime. Even fetch and crypto run at native speed.

ImpellerRust FFIfetchcryptotimersstreamszlibfsbytecode

Easy to extend

Write a Dart class, add a JSX type, register it. Any Flutter widget becomes a JSX element.

// JSX type
badge: { label: string; color?: ColorInput };

// Dart widget
class FuseBadge extends StatelessWidget {
  const FuseBadge(this.node);
  final FuseNode node;

  @override
  Widget build(BuildContext context) {
    return Chip(label: Text(node.string('label') ?? ''));
  }
}

// Register
runtime.registerWidget('badge', FuseBadge.new);

Hot reload

Vite HMR on a real device. Edit, save, see it update — without restarting Flutter.

terminal
$ bun dev
┌ vite dev server running
├ flutter: launching...
✓ connected
hmr update App.tsx 12ms
hmr update Header.tsx 8ms
02 — architecture

From signal to pixel

TypeScript runs in QuickJS, embedded via FFI. Signals flow directly to native widgets.

SolidJS
your code
QuickJS
runtime
Rust FFI
bridge
Flutter
widgets
Impeller
pixels
03 — two ecosystems

The best of both worlds

TypeScript for your app logic. Flutter for rendering. You don't compromise on either.

WHAT TYPESCRIPT GIVES YOU
//SolidJS signals for state and UI
//Your existing npm packages
//Vite HMR on a real device
//Ship updates without the App Store
//No Dart required to build features
WHAT FLUTTER GIVES YOU
//Impeller GPU rendering on every platform
//Pixel-perfect UI without platform quirks
//Add a widget in one Dart class
//Full access to any pub.dev package
//Share extensions on npm
04 — comparison

How it stacks up

solid-fusereact nativefluttercapacitor
languageTypeScriptJS / TSDartJS / TS
renderingImpeller (GPU)native viewsImpeller (GPU)webview
reactivitysignalsVDOM diffsetStateVDOM diff
npm ecosystem
pixel-perfect
ota updatesbuilt-incodepushnative

Start building.

Zero to running app in under a minute.

$bunx create-solid-fuse my-app