Full-Stack Dart for the
JavaScript Ecosystem

Write React, React Native, and Express applications entirely in Dart. One language. Runtime type safety. Sound null safety. No compromises.

// A complete Express server in Dart
import 'package:dart_node_express/dart_node_express.dart';

void main() {
  final app = express();

  app.get('/', handler((req, res) {
    res.jsonMap({'message': 'Hello from Dart!'});
  }));

  app.listen(3000, () {
    print('Server running on port 3000');
  }.toJS);
}

dart_node is a collection of Dart packages for full-stack JavaScript development. It provides typed bindings to React, React Native, Express.js, WebSockets, and SQLite. Unlike TypeScript, Dart preserves types at runtime and has sound null safety. Use one language for frontend, backend, and mobile with access to the entire npm ecosystem.

Built for You

Whether you're coming from React or Flutter, dart_node speaks your language.

For React & TypeScript Developers

Same hooks, components, and patterns you know - with runtime type safety TypeScript cannot provide.

React (TypeScript)
const Counter: React.FC = () => {
  const [count, setCount] = useState<number>(0);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count}
    </button>
  );
};
React (Dart)
ReactElement counter() {
  final count = useState(0);

  return button(
    text: 'Count: ${count.value}',
    onClick: () => count.setWithUpdater((c) => c + 1),
  );
}
1

Same Paradigms

Hooks, components, props, state — everything you know from React works the same way in Dart.

2

Runtime Type Safety

Unlike TypeScript, Dart preserves types at runtime. No more any escapes or erased generics.

3

Simpler Tooling

No webpack, no babel, no tsconfig. Just dart compile js and you're done.

For Flutter Developers

Use your Dart skills for web and Node.js. Access the React and npm ecosystems while writing pure Dart.

Flutter
class Counter extends StatefulWidget {
  
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

  
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => setState(() => count++),
      child: Text('Count: $count'),
    );
  }
}
dart_node React
ReactElement counter() {
  final count = useState(0);

  return button(
    text: 'Count: ${count.value}',
    onClick: () => count.setWithUpdater((c) => c + 1),
  );
}
1

Same Language

Use your existing Dart skills. Share models, utilities, and business logic across platforms.

2

Web Ecosystem Access

Leverage the massive React and npm ecosystems while writing pure Dart code.

3

Full-Stack Dart

Backend (Express), web (React), mobile (React Native) — all in one language.

The dart_node Stack

Packages and tools that give you full-stack superpowers.

C

dart_node_core

Foundation layer with JS interop utilities, Node.js bindings, and console helpers.

Learn more →
E

dart_node_express

Type-safe Express.js bindings for building HTTP servers and REST APIs.

Learn more →
R

dart_node_react

React bindings with hooks, JSX-like syntax, and full component support.

Learn more →
N

dart_node_react_native

React Native + Expo bindings for cross-platform mobile development.

Learn more →
W

dart_node_ws

WebSocket bindings for real-time communication on Node.js.

Learn more →
M

dart_node_mcp

Model Context Protocol server bindings for building AI tool servers.

Learn more →
S

dart_node_better_sqlite3

Typed bindings for better-sqlite3 with synchronous SQLite3 and WAL mode.

Learn more →
X

reflux

Redux-style predictable state container with exhaustive pattern matching.

Learn more →
L

dart_logging

Pino-style structured logging with child loggers and transports.

Learn more →
J

dart_jsx

JSX transpiler for Dart — write JSX syntax that compiles to dart_node_react calls.

Learn more →
V

dart_node_vsix

VSCode extension API bindings for building Visual Studio Code extensions in Dart.

Learn more →
T

too-many-cooks

Multi-agent coordination MCP server for AI agents editing codebases simultaneously.

Learn more →

Dart vs TypeScript: Feature Comparison

A direct comparison of type system capabilities.

Feature TypeScript Dart
Runtime type preservation No (erased) Yes
Sound null safety Partial (!) Yes
Generic type checking at runtime No Yes
JSON validation at boundary Needs Zod/io-ts Built-in
Build tooling required Webpack/Babel/etc dart compile js
npm ecosystem access Native Via JS interop

Why Types Matter at Runtime

TypeScript erases types when it compiles to JavaScript. Dart doesn't.

TypeScript (Types Erased)
interface User {
  id: number;
  name: string;
}

// At runtime, this is just a plain object
// No way to validate the shape!
const user: User = JSON.parse(data);

// This could fail silently
console.log(user.name.toUpperCase());
// Runtime error if name is undefined!
Dart (Types Preserved)
class User {
  final int id;
  final String name;
  User({required this.id, required this.name});
}

// Types exist at runtime - you can validate!
final user = User.fromJson(jsonDecode(data));

// If name were null, this would fail
// at deserialization, not at usage
print(user.name.toUpperCase());

Get Started in Minutes

# Create a new project
mkdir my_dart_app && cd my_dart_app
dart create -t package .

# Add dart_node packages
dart pub add dart_node_core dart_node_express

# Write your server
cat > lib/server.dart << 'EOF'
import 'package:dart_node_express/dart_node_express.dart';

void main() {
  final app = express();
  app.get('/', handler((req, res) => res.send('Hello, Dart!')));
  app.listen(3000);
}
EOF

# Compile to JavaScript and run
dart compile js lib/server.dart -o build/server.js
node build/server.js