When to use Flutter Qjs Next
Flutter Qjs Next brings the lightweight QuickJS engine directly into your Flutter and Dart projects through native FFI bindings. By compiling QuickJS as a shared library for each target platform, the package enables you to evaluate, compile, and execute JavaScript code at runtime without leaving the Flutter sandbox. This opens the door to dynamic scripting, on‑the‑fly UI adjustments, and sandboxed plugin architectures that would otherwise require a heavyweight JavaScript runtime or a full‑blown web view.
The core of the package is a thin Dart wrapper around the C API of QuickJS. All heavy lifting—parsing, byte‑code generation, and garbage collection—is performed by the native library, while the Dart side simply forwards calls via `dart:ffi`. Because QuickJS is designed for embedded use, the engine starts up in a few milliseconds and consumes a fraction of the memory of larger runtimes like V8. The result is a responsive scripting layer that works equally well on low‑end Android devices and high‑performance desktop machines.
Use cases for Flutter Qjs Next are diverse. Mobile games can load level‑specific logic written in JavaScript, allowing designers to tweak gameplay without rebuilding the app. Enterprise applications can expose a safe scripting console for power users to create custom data‑transform pipelines. Content‑driven apps can fetch remote JavaScript snippets that render UI components on the fly, reducing the need for frequent releases. Because the engine runs in a separate isolate from the UI thread, you can safely execute long‑running scripts without stalling animations or input handling.
Getting started is straightforward. After adding the dependency with `flutter pub add flutter_qjs_next`, run `flutter pub get` and let the build system compile the native binaries for Android, iOS, macOS, Linux, and Windows. The package automatically selects the correct shared library based on the host platform, but you should verify that the required toolchains (NDK for Android, Xcode for iOS/macOS) are installed. In production, be mindful of memory usage—each `JSContext` holds its own heap, so reuse contexts when possible. Security is another consideration: treat any JavaScript received from external sources as untrusted, and sandbox it by disabling native bindings and limiting the exposed Dart API.
Architecturally, Flutter Qjs Next fits neatly into a clean‑separation pattern. Create a dedicated service class that owns a `JSRuntime` and a pool of `JSContext` objects, inject it via your preferred state‑management solution (Provider, Riverpod, Bloc, etc.), and expose high‑level methods that translate Dart data structures to JavaScript values. This keeps the FFI layer isolated from UI code and makes unit testing easier—mock the service and verify that your business logic behaves correctly regardless of the scripting engine. As the package evolves, you can upgrade the underlying QuickJS version without changing any Dart code, ensuring long‑term maintainability for apps that rely on runtime extensibility.
Pros
- tiny footprint and fast start‑up
- native performance via C engine
- single API works on all major platforms
- no need for a full web view
- easy to sandbox and control
Watch outs
- requires native toolchains for each platform
- no built‑in support for web (dart:ffi limitation)
- manual memory management of JS contexts
- limited standard library compared to V8
Setup notes
1. Add the package: `flutter pub add flutter_qjs_next` 2. Run `flutter pub get` to fetch the dependency. 3. Ensure platform toolchains are installed (Android NDK, Xcode, etc.). 4. Rebuild the project (`flutter run` or `flutter build`) so the native QuickJS binaries are compiled for your target. 5. Import the library in Dart: `import 'package:flutter_qjs_next/flutter_qjs_next.dart';` 6. Create a `JSRuntime` and `JSContext` before evaluating scripts. Dispose them when no longer needed.
Native binaries are provided for Android (arm64, armeabi‑v7a, x86_64), iOS (arm64, x86_64 simulator), macOS (arm64, x86_64), Linux (x86_64, arm64), and Windows (x86_64). Web platforms are not supported because `dart:ffi` is unavailable in browsers.
import 'package:flutter_qjs_next/flutter_qjs_next.dart';
void main() async {
final runtime = await JSRuntime.create();
final context = await runtime.createContext();
// Simple evaluation
final result = await context.evaluate('1 + 2 * 3');
print('Result: ${result.toInt()}'); // prints 7
// Expose a Dart function to JavaScript
await context.setProperty('log', JSFunction((args) {
print('JS says: ${args[0]}');
return JSValue.undefined();
}));
await context.evaluate('log("Hello from JS!")');
// Clean up
await context.dispose();
await runtime.dispose();
}